8

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

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

我可能应该注意到 UITableView 包含在 iPad 上 UISplitViewController 的 MasterViewController 中。

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

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 值没有意义 - 同一行的值被多次记录 - 而其他行则没有完全被记录。

编辑:根据要求提供一些代码:

    - (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"];
        }
    }

}
4

3 回答 3

8

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

于 2012-05-11T09:25:27.563 回答
3

您很可能是从其他方法调用的:

UITableViewCell *cell = [self.tableView cellForRowAtIndexPath:indexPath];

外部的 self.tableView- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath将调用 cellForRowAtIndexPath 两次。

于 2015-04-08T15:17:41.150 回答
0

迅速

DispatchQueue.main.async {
   //Add selection in main queue
}

这将解决问题。

于 2019-07-19T07:51:10.213 回答