0

我已經分組了UITableView。UITableViewHeaderFooterView標題視圖顯示在reloadData上一半的時間

這是我的標題視圖方法 - 注意我做它只加載一次和下一次,而不是重新加載元素,它只是返回headerView,如果它已經有子視圖了(我需要這個,因爲我有元素在headerView中改變狀態,我不想讓他們重新加載):

-(UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section{ 
static NSString *headerReuseIdentifier = @"myHeader"; 

UITableViewHeaderFooterView *headerView = [tableView dequeueReusableHeaderFooterViewWithIdentifier:headerReuseIdentifier]; 
if (headerView == nil) { 
    headerView = [[UITableViewHeaderFooterView alloc] initWithReuseIdentifier:headerReuseIdentifier];//[tableView dequeueReusableHeaderFooterViewWithIdentifier:headerReuseIdentifier]; 
    CGRect frame=CGRectMake(0, 0, tableView.bounds.size.width, 44); 
    headerView.frame=frame; 
} 

if (headerView.contentView.subviews.count!=0){ 
    return headerView;//do not reload 
} 
    UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(5, 0, tableView.frame.size.width-85, 44)]; 
    [label setFont:[UIFont boldSystemFontOfSize:16]]; 
    NSString *[email protected]"not found"; 
    [label setText:name]; 

    headerView.backgroundColor=[UIColor clearColor]; 
    [headerView.contentView addSubview:label]; 
    //... etc elements 

return headerView; 
} 

我實現類似的邏輯對細胞也一樣,即它們不刷新的元素,如果子視圖已經添加到細胞,只是爲了看看它是如何工作有太多:

​​

================= ================================================== ==

在這裏它的外觀的第一時間,注意步驟:1和第2步:在正確的升序現在enter image description here

的問題,當[myTableView reloadData]被稱爲表看起來像這樣:enter image description here

注意:headerView視圖是倒退的!但是,單元格總是以正確的順序顯示。

如果再次調用[myTableView reloadData] - headerViews將以正確的順序顯示。

我可以通過避免調用reloadData來阻止這種情況發生,但我需要重新加載單元格中的數據,而不是在headerViews中。

有沒有人經歷過這個headerViews翻轉 - 你是如何修復它?

的Xcode 8.3.2,在iPad iOS9.0模擬器運行

,可用來測試這個錯誤的頭意見重新排序全碼:

.h文件中

@interface TableTestViewController : UIViewController 
@property(strong,nonatomic)IBOutlet UITableView *myTable; 
@property(strong,nonatomic)NSMutableArray *steps; 
@end 

.m文件

#import "TableTestViewController.h" 

@interface TableTestViewController() 

@end 

@implementation TableTestViewController 
@synthesize steps,myTable; 

- (void)viewDidLoad { 
[super viewDidLoad]; 
steps=[[NSMutableArray alloc]initWithObjects:@"Step 1",@"Step 2", nil]; 
} 

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { 
return steps.count; 
} 

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { 
return 1; 
} 

-(CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section{ 
return 44.0; 
} 

-(UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section{ 
static NSString *headerReuseIdentifier = @"myHeader"; 

UITableViewHeaderFooterView *headerView = [tableView dequeueReusableHeaderFooterViewWithIdentifier:headerReuseIdentifier]; 
if (headerView == nil) { 
    headerView = [[UITableViewHeaderFooterView alloc] initWithReuseIdentifier:headerReuseIdentifier];//[tableView dequeueReusableHeaderFooterViewWithIdentifier:headerReuseIdentifier]; 
    CGRect frame=CGRectMake(0, 0, tableView.bounds.size.width, 44); 
    headerView.frame=frame; 
} 

if (headerView.contentView.subviews.count!=0) { 
    return headerView;//do not reload when running 
} 

while (headerView.contentView.subviews.count) { 
    id subview=[headerView.contentView.subviews objectAtIndex:0]; 
    [subview removeFromSuperview]; 
} 

headerView.backgroundColor=[UIColor clearColor]; 

UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(5, 0, tableView.frame.size.width-85, 44)]; 
[label setFont:[UIFont boldSystemFontOfSize:16]]; 
[label setText:[steps objectAtIndex:section]]; 


[headerView.contentView addSubview:label]; 

    int btnSz=tableView.bounds.size.width/6; 
    UIButton *startStepBtn = [[UIButton alloc]initWithFrame:CGRectMake(btnSz*5+5 ,5, 30, 30)]; 
    [startStepBtn setTitle:@"" forState:UIControlStateNormal]; 
    startStepBtn.tag=section+1000; 
    startStepBtn.enabled=NO; 
    [startStepBtn addTarget:self action:@selector(startStep:) forControlEvents:(UIControlEvents)UIControlEventTouchUpInside]; 

    [headerView.contentView addSubview:startStepBtn]; 


return headerView; 
} 

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{ 
int i=1; 
return 60*ceil((double)i/5)+10; 
} 
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { 
static NSString *CellIdentifier = @"Cell"; 

UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier]; 
if (cell == nil) { 
    cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier]; 
} 

if ([cell.contentView.subviews count]!=0) { 
    return cell;//do not reload when running 
} 

//clear 1st 
while([cell.contentView.subviews count]){ 
    id subview = [cell.contentView.subviews objectAtIndex:0]; 
    [subview removeFromSuperview]; 
} 

int btnSz=tableView.bounds.size.width/6; 

UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(5, 0, tableView.frame.size.width-85, 44)]; 
[label setFont:[UIFont boldSystemFontOfSize:16]]; 
[label setText:[steps objectAtIndex:indexPath.section]]; 
[cell.contentView addSubview:label]; 

CGRect frame; 

frame = CGRectMake(btnSz*5+5 ,5, 30, 30); 
    UIButton *delStepBtn = [[UIButton alloc]initWithFrame:frame]; 
    [delStepBtn setTitle:@"❌" forState:UIControlStateNormal]; 
    [delStepBtn addTarget:self action:@selector(deleteStep:) forControlEvents:(UIControlEvents)UIControlEventTouchUpInside]; 
    [cell.contentView addSubview:delStepBtn]; 

    frame = CGRectMake(btnSz*5+5 ,5+30, 30, 30); 
    UIButton *editStepBtn = [[UIButton alloc]initWithFrame:frame]; 
    [editStepBtn setTitle:@"" forState:UIControlStateNormal]; 
    [editStepBtn addTarget:self action:@selector(editStep:) forControlEvents:(UIControlEvents)UIControlEventTouchUpInside]; 
    [cell.contentView addSubview:editStepBtn]; 

return cell; 
} 

-(void)editStep:(id)sender{ 
[myTable reloadData]; 
} 

@end 

實現,你會看到擡頭順序的標題,觸摸錘鈕mak es表重新加載並且標題現在將按降序排列,再次觸摸並返回升序。

但是,單元格內容始終保持原樣按升序排列。

回答

1

UITableViewHeaderFooterView是可重複使用的視圖,因此您不能確定UITableView每次都會返回完全相同的視圖。

我建議創建一個UITableViewHeaderFooterView的子類,並在某些數據源中保存外部狀態。

如果您不想這樣做,作爲解決方法,您可以爲每個部分使用唯一的重用標識符。 在這種情況下,你應該用

NSString *headerReuseIdentifier = [NSString stringWithFormat: @"myHeader%ld", (long)section];

+0

您的解決方法作爲一種魅力工作,即爲標題分配唯一的標識符。萬分感謝! –

0

那檢查你正在做是沒有必要的:

if (headerView.contentView.subviews.count!=0){ 
    return headerView;//do not reload 
} 

然而,這不是一個好的做法實例化一個UILabel每次。 每個實例化應該在if (headerView == nil)的情況下完成,並且UILabel應該是該頭或單元的屬性。

比你的方式,你可以改變text屬性,當你出隊頭/單元格。

+0

權代替

static NSString *headerReuseIdentifier = @"myHeader";

,但它仍然在錯誤的順序返回頭也是這樣的。 –

+0

你能發送你的最新代碼嗎? –

+0

使用唯一標識符添加完整代碼 –