UITableView cellForRowAtIndexPath为每一行调用多次 [英] UITableView cellForRowAtIndexPath called more than once for each row

查看:90
本文介绍了UITableView cellForRowAtIndexPath为每一行调用多次的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如果我有一个包含4行的UITableView,那么当我导航到该视图时,不应该调用4次cellForRowAtIndexPath方法吗?我发现它被多次调用,例如如果有4行,当我深入到UITable视图时会调用8次,然后当我导航回到同一个UITableView时调用12次。

If I have a UITableView that has 4 rows in it then shouldn't the cellForRowAtIndexPath method be called 4 times when I navigate to that view? I am finding that it is being called multiple times e.g. if there are 4 rows it is called 8 times when I drill down into the UITable view and then 12 times when I navigate back up to the same UITableView.

我只是误解了这种方法的工作原理?我认为应该为显示的每一行调用一次(不涉及滚动,因为表格视图的内容很容易适合我的iPad屏幕)。

Am I just misunderstanding how this method works? I thought it should be called once for each row that is displayed (there is no scrolling involved as the contents of the table view easily fits on my iPad screen).

I应该注意UITableView包含在iPad上的UISplitViewController的MasterViewController中。

I should probably note that the UITableView is contained in the MasterViewController of a UISplitViewController on an iPad.

编辑:我得到的真正问题是以下代码的方式不一致正在应用:

The real problem I am getting is inconsistency in the way that the following code is being applied:

if (selectedNavItem.folder.isAssignedToUser != [NSNumber numberWithInt:1]) 
        {
            NSLog(@"%@", cell.textLabel.text);
            cell.selectionStyle = UITableViewCellSelectionStyleNone;
            cell.userInteractionEnabled = NO;
            cell.textLabel.enabled = NO;
            cell.detailTextLabel.text = @"Access not granted";
            cell.detailTextLabel.enabled = NO;
        }

当我第一次深入到导航堆栈的特定级别时他们应该工作。但是后来如果我向上或向下导航,那么我发现各行被错误地处理,即当它们应该被启用时它们最终被禁用。这导致我提出了一个断点和一些日志记录代码,试图找出发生了什么。我发现上面的代码被调用的次数比行数多 - 而且我记录的cell.textLabel.text值没有意义 - 同一行的值被多次记录 - 而其他行则没有记录完毕。

When I first "drill down" to a particular level of my navigation stack things work as they should. But later if I navigate back up or down then I find that various rows get treated incorrectly i.e. they end up disabled when they should be enabled. That led me to put a break point in and some logging code to try to find out what was going on. I found that the code above was being called more times than there was rows - and the cell.textLabel.text value that I was logging did not make sense - a value for the same row was being logged multiple times - and other rows were not being logged at all.

编辑:按要求提供一些代码:

Providing some code as requested:

    - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *CellIdentifier = @"FolderCell";

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    [self configureCell:cell atIndexPath:indexPath];
    return cell;
}


- (NSFetchedResultsController *)fetchedResultsController
{
    if (__fetchedResultsController != nil) {
        return __fetchedResultsController;
    }

    // Set up the fetched results controller.
    // Create the fetch request for the entity.
    NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
    // Edit the entity name as appropriate.
    NSEntityDescription *entity = [NSEntityDescription entityForName:@"NavItem" inManagedObjectContext:self.managedObjectContext];
    [fetchRequest setEntity:entity];

    // Set the batch size to a suitable number.
    [fetchRequest setFetchBatchSize:20];

    // Edit the sort keys as appropriate.
    NSSortDescriptor *sortDescriptor1 = [[NSSortDescriptor alloc] initWithKey:@"sortOrder" ascending:YES];
    NSSortDescriptor *sortDescriptor2 = [[NSSortDescriptor alloc] initWithKey:@"name" ascending:YES selector:@selector(localizedCaseInsensitiveCompare:)];
    NSArray *sortDescriptors = [NSArray arrayWithObjects:sortDescriptor1, sortDescriptor2, nil];

    [fetchRequest setSortDescriptors:sortDescriptors];

    // Edit the section name key path and cache name if appropriate.
    // nil for section name key path means "no sections".
    NSFetchedResultsController *aFetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:self.
        managedObjectContext sectionNameKeyPath:nil cacheName:@"Master"];
    aFetchedResultsController.delegate = self;
    self.fetchedResultsController = aFetchedResultsController;

    NSError *error = nil;
    if (![self.fetchedResultsController performFetch:&error]) {
        /*
         Replace this implementation with code to handle the error appropriately.

         abort() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development. 
         */
        NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
        abort();
    }

    return __fetchedResultsController;
}   

- (void)configureCell:(UITableViewCell *)cell atIndexPath:(NSIndexPath *)indexPath
{
    NSManagedObject *managedObject = [self.fetchedResultsController objectAtIndexPath:indexPath];
    NavItem *selectedNavItem = (NavItem *)managedObject;
    cell.textLabel.text = [[managedObject valueForKey:@"name"] description];
    cell.detailTextLabel.text = @"";

    if (selectedNavItem.folder != nil) {
        cell.imageView.image = [UIImage imageNamed:@"Folder.png"];


        //NSLog(@"%@", selectedNavItem.folder.isAssignedToUser);

        if (selectedNavItem.folder.isAssignedToUser != [NSNumber numberWithInt:1]) 
        {
            NSLog(@"%@", cell.textLabel.text);
            cell.selectionStyle = UITableViewCellSelectionStyleNone;
            cell.userInteractionEnabled = NO;
            cell.textLabel.enabled = NO;
            cell.detailTextLabel.text = @"Access not granted";
            cell.detailTextLabel.enabled = NO;
        }
    }
    else if (selectedNavItem.document != nil) {
        cell.detailTextLabel.text  = [[selectedNavItem.document valueForKey:@"itemDescription"] description];

        if ([[selectedNavItem.document.fileName pathExtension] isEqualToString:@"pdf"]) 
        {
            cell.imageView.image = [UIImage imageNamed:@"pdf.png"];
        }
        else if ([[selectedNavItem.document.fileName pathExtension] isEqualToString:@"doc"] || [[selectedNavItem.document.fileName pathExtension] isEqualToString:@"docx"]) 
        {
            cell.imageView.image = [UIImage imageNamed:@"Word-32x32.png"];
        }
        else if ([[selectedNavItem.document.fileName pathExtension] isEqualToString:@"xls"] || [[selectedNavItem.document.fileName pathExtension] isEqualToString:@"xlsx"]) 
        {
            cell.imageView.image = [UIImage imageNamed:@"Excel-32x32.png"];
        }
        else if ([[selectedNavItem.document.fileName pathExtension] isEqualToString:@"ppt"] || [[selectedNavItem.document.fileName pathExtension] isEqualToString:@"pps"]) 
        {
            cell.imageView.image = [UIImage imageNamed:@"Powerpoint-32x32.png"];
        }
        else if ([[selectedNavItem.document.fileName pathExtension] isEqualToString:@"mp3"] || [[selectedNavItem.document.fileName pathExtension] isEqualToString:@"wav"]) 
        {
            cell.imageView.image = [UIImage imageNamed:@"65-note.png"];
        }
        else if ([[selectedNavItem.document.fileName pathExtension] isEqualToString:@"mp4"] || [[selectedNavItem.document.fileName pathExtension] isEqualToString:@"mov"]) 
        {
            cell.imageView.image = [UIImage imageNamed:@"46-movie-2.png"];
        }
        else if ([[selectedNavItem.document.fileName pathExtension] isEqualToString:@"ibooks"]) 
        {
            cell.imageView.image = [UIImage imageNamed:@"ibooks-icon.png"];
        }
        else if ([[selectedNavItem.document.fileName pathExtension] isEqualToString:@"png"] || [[selectedNavItem.document.fileName pathExtension] isEqualToString:@"bmp"] || [[selectedNavItem.document.fileName pathExtension] isEqualToString:@"jpg"] || [[selectedNavItem.document.fileName pathExtension] isEqualToString:@"jpeg"] || [[selectedNavItem.document.fileName pathExtension] isEqualToString:@"tif"] || [[selectedNavItem.document.fileName pathExtension] isEqualToString:@"tiff"] || [[selectedNavItem.document.fileName pathExtension] isEqualToString:@"gif"]) 
        {
            cell.imageView.image = [UIImage imageNamed:@"41-picture-frame.png"];
        }
        else 
        {
            cell.imageView.image = [UIImage imageNamed:@"179-notepad.png"];
        }


    }
    else if (selectedNavItem.attachment != nil) {
        cell.detailTextLabel.text  = [[selectedNavItem.attachment valueForKey:@"itemDescription"] description];

        if ([[selectedNavItem.attachment.fileName pathExtension] isEqualToString:@"pdf"]) 
        {
            cell.imageView.image = [UIImage imageNamed:@"pdf.png"];
        }
        else if ([[selectedNavItem.attachment.fileName pathExtension] isEqualToString:@"doc"] || [[selectedNavItem.attachment.fileName pathExtension] isEqualToString:@"docx"]) 
        {
            cell.imageView.image = [UIImage imageNamed:@"Word-32x32.png"];
        }
        else if ([[selectedNavItem.attachment.fileName pathExtension] isEqualToString:@"xls"] || [[selectedNavItem.attachment.fileName pathExtension] isEqualToString:@"xlsx"]) 
        {
            cell.imageView.image = [UIImage imageNamed:@"Excel-32x32.png"];
        }
        else if ([[selectedNavItem.attachment.fileName pathExtension] isEqualToString:@"ppt"] || [[selectedNavItem.attachment.fileName pathExtension] isEqualToString:@"pps"]) 
        {
            cell.imageView.image = [UIImage imageNamed:@"Powerpoint-32x32.png"];
        }
        else if ([[selectedNavItem.attachment.fileName pathExtension] isEqualToString:@"mp3"]) 
        {
            cell.imageView.image = [UIImage imageNamed:@"65-note.png"];
        }
        else if ([[selectedNavItem.attachment.fileName pathExtension] isEqualToString:@"mp4"]) 
        {
            cell.imageView.image = [UIImage imageNamed:@"46-movie-2.png"];
        }
        else if ([[selectedNavItem.document.fileName pathExtension] isEqualToString:@"ibooks"]) 
        {
            cell.imageView.image = [UIImage imageNamed:@"ibooks-icon.png"];
        }
        else if ([[selectedNavItem.attachment.fileName pathExtension] isEqualToString:@"png"] || [[selectedNavItem.attachment.fileName pathExtension] isEqualToString:@"bmp"] || [[selectedNavItem.attachment.fileName pathExtension] isEqualToString:@"jpg"] || [[selectedNavItem.attachment.fileName pathExtension] isEqualToString:@"jpeg"] || [[selectedNavItem.attachment.fileName pathExtension] isEqualToString:@"tif"] || [[selectedNavItem.attachment.fileName pathExtension] isEqualToString:@"tiff"] || [[selectedNavItem.attachment.fileName pathExtension] isEqualToString:@"gif"]) 
        {
            cell.imageView.image = [UIImage imageNamed:@"41-picture-frame.png"];
        }
        else 
        {
            cell.imageView.image = [UIImage imageNamed:@"179-notepad.png"];
        }
    }

}


推荐答案

当单元格出现时调用该方法,因此每当单元格出现时,都会调用该方法。此外,细胞被重复使用。因此,即使特定单元格的方法被调用一次,也可能在此单元格消失然后再次出现时再调用一次。

The method is called when the cell appears, so whenever a cell appears, the method is called. Also, the cells are reused. So even if the method for a particular cell is called once, it maybe called for another time when this cell disappears and then appears again.

这篇关于UITableView cellForRowAtIndexPath为每一行调用多次的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆