UITableview 在 reloadData 后保留旧单元格

Posted

技术标签:

【中文标题】UITableview 在 reloadData 后保留旧单元格【英文标题】:UITableview keeps old cells after reloadData 【发布时间】:2013-08-08 00:21:01 【问题描述】:

我有一个底部有一个tabBar 和一个tableview 的视图。当按下 barButtonItem 时,保存 tableview 数据的数组会发生变化。

使用 NSLogs,很明显数组确实在发生变化,因为 [NSArray count] 显示不同的值。但是,当我使用 [UITableview reloadData] 时,单元格保持不变。

如果我向上滚动一点然后向下滚动,屏幕外的任何内容都会更新。我猜这是因为当它离开屏幕时,它会出列,当它回来时,它会用新数据重绘。有没有办法让它重绘所有内容?

#import "TableViewController.h"

@interface TableViewController ()

@end

@implementation TableViewController
@synthesize listBar,selectedTab , linkTableView, barButton5, barButton4, barButton3, barButton2, barButton1, Lists, imageID, titleID, linkID, cells;


- (void)viewDidLoad

    [super viewDidLoad];
    linkTableView = [[UITableView    alloc] init];
    Lists         = [[NSArray        alloc] init];
    imageID       = [[NSMutableArray alloc] init];
    titleID       = [[NSMutableArray alloc] init];
    linkID        = [[NSMutableArray alloc] init];
    linkTableView.delegate   = self;
    linkTableView.dataSource = self;


-(void)viewWillAppear:(BOOL)animated
    NSArray *barItems = [[NSArray alloc] initWithObjects:barButton1, barButton2, barButton3, barButton4, barButton5, nil];
    listBar.selectedItem = [barItems objectAtIndex:selectedTab];

    //when view will appear load data dependent on selectedTab
    [self performSelector:@selector(updateTable)];


- (void)didReceiveMemoryWarning

    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.


-(void)tabBar:(UITabBar *)tabBar didSelectItem:(UITabBarItem *)item
    selectedTab = item.tag;
    [self performSelector:@selector(updateTable)];


-(void)updateTable
    [imageID removeAllObjects];
    [titleID removeAllObjects];
    [linkID removeAllObjects];


    //load from the xml file
    RXMLElement *rxml = [RXMLElement elementFromXMLFile:@"Lists.xml"];
    //makes an array from the list children
    Lists = [rxml children:@"List"];
    cells = [[Lists objectAtIndex:selectedTab] children:@"Cell"];
    [rxml iterateElements:cells usingBlock:^(RXMLElement *cellElement) 
        [imageID addObject:[cellElement child:@"ImageName"]];
        [titleID addObject:[cellElement child:@"CellText" ]];
        [linkID  addObject:[cellElement child:@"Link"     ]];
    ];

    NSLog(@"Count is %i", [cells count]);
    [linkTableView reloadData];


#pragma mark - Table view data source

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView

    // Return the number of sections.
    return 1;


- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section

    // Return the number of rows in the section.
    return [cells count];


-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
    return 60;


- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath


    static NSString *CellIdentifier = @"LinkCell";
    linkCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
    if (cell == nil) 
        cell = [[linkCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
    

    // Configure the cell...
    NSString *imageName = [NSString stringWithFormat:@"%@", [imageID objectAtIndex:indexPath.row]];
    cell.image.image = [UIImage imageNamed:imageName];
    NSString *labelText = [NSString stringWithFormat:@"%@", [titleID objectAtIndex:indexPath.row]];
    cell.linkCellLabel.text = labelText;
    return cell;


/*
// Override to support conditional editing of the table view.
- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath

    // Return NO if you do not want the specified item to be editable.
    return YES;

*/

/*
// Override to support editing the table view.
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath

    if (editingStyle == UITableViewCellEditingStyleDelete) 
        // Delete the row from the data source
        [tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationFade];
       
    else if (editingStyle == UITableViewCellEditingStyleInsert) 
        // Create a new instance of the appropriate class, insert it into the array, and add a new row to the table view
       

*/

/*
// Override to support rearranging the table view.
- (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)fromIndexPath toIndexPath:(NSIndexPath *)toIndexPath


*/

/*
// Override to support conditional rearranging of the table view.
- (BOOL)tableView:(UITableView *)tableView canMoveRowAtIndexPath:(NSIndexPath *)indexPath

    // Return NO if you do not want the item to be re-orderable.
    return YES;

*/

#pragma mark - Table view delegate

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath

    // Navigation logic may go here. Create and push another view controller.
    /*
     <#DetailViewController#> *detailViewController = [[<#DetailViewController#> alloc] initWithNibName:@"<#Nib name#>" bundle:nil];
     // ...
     // Pass the selected object to the new view controller.
     [self.navigationController pushViewController:detailViewController animated:YES];
     */


@end

【问题讨论】:

【参考方案1】:

从您的代码中删除这一行:linkTableView = [[UITableView alloc] init];

或您的 uitableview 的任何其他初始化程序 并使用此代码更新部分

  [self.tableView beginUpdates];
NSMutableIndexSet* index = [[NSMutableIndexSet alloc]init];
[index addIndex:0];
[self.tableView reloadSections:index withRowAnimation:UITableViewRowAnimationAutomatic];
[self.tableView endUpdates];

【讨论】:

以上是关于UITableview 在 reloadData 后保留旧单元格的主要内容,如果未能解决你的问题,请参考以下文章

在 UITableView 上延迟 reloadData

iOS UITableView reloadData 刷新结束后执行后续操作

UITableView 没有在 reloadData 上重新加载

ReloadData (UITableView) 不起作用

UITableView 在 reloadData 后自动向下滚动

UITableView 奇怪的 reloadData 问题