【问题标题】:UITableView reloadData - cellForRowAtIndexPath not firedUITableView reloadData - cellForRowAtIndexPath 未触发
【发布时间】:2010-08-12 18:41:30
【问题描述】:

我有 splitViewController,它有一些 viewController 作为 MasterViewController 和一些 tableViewController 作为 DetailViewController。当我按下 masterViewController 上的按钮时,我想在 detailViewController 中显示新的 tableViewController 而不是现有的。

所以我这样做了:

SearchDetailViewController *searchDetailViewController = [[SearchDetailViewController alloc] initWithStyle:UITableViewStylePlain];
UINavigationController *searchDetailNavigationController = [[UINavigationController alloc] initWithRootViewController:searchDetailViewController];

之后我传递数据以显示在新的 tableController 中:

[searchDetailViewController passInSearchResults:listOfItems];

之后我将新控制器“推送”到 splitViewController:

[searchSplitViewController setViewControllers:[NSArray arrayWithObjects:self.navigationController, searchDetailNavigationController, nil]];

在目标tableViewController 方法“passInSearchResults”中传递了数据,我也调用了reloadData。方法如下:

- (void)passInSearchResults:(NSMutableDictionary *)searchResults {
    self.searchResultList = searchResults;
    NSLog(@"Data is passed in: %@",self.searchResultList);
    [self.tableView reloadData];
    //[self.tableView setNeedsDisplay];
}

控制台:数据传入:[这里我得到了我想要的确切数据,而且看起来恰到好处]。

After this I see that method "numberOfRowsInSection" is fired:
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
    NSLog(@"Setting table length: %i",[self.searchResultList count]);
    return [self.searchResultList count];
}

控制台:设置表格长度:[这里我得到正确的长度]

问题是表格没有被传递的数据填充并且方法“cellForRowAtIndexPath”没有被调用。

怎么可能在 reloadData 方法“numberOfRowsInSection”被触发,但没有方法“cellForRowAtIndexPath”...... ???

谢谢

【问题讨论】:

    标签: iphone uitableview reloaddata


    【解决方案1】:

    调用[self.tableView reloadData];时检查你是否在主线程中

    - (void)passInSearchResults:(NSMutableDictionary *)searchResults {
     if ([NSThread isMainThread]) {
        self.searchResultList = searchResults;
        NSLog(@"Data is passed in: %@",self.searchResultList);
        [self.tableView reloadData];
    }
    else {
        [self performSelectorOnMainThread:@selector(passInSearchResults:) searchResults waitUntilDone:NO];
    }
    

    }

    【讨论】:

    • 不必先检查是否在主线程上运行。 performSelectorOnMainThread 有效,即使您已经在主线程上,dispatch_async( dispatch_get_main_queue() 也是如此(这可能是您真正想要的)。在此处添加 if 只会消耗不必要的处理器周期。
    【解决方案2】:

    怎么可能在 reloadData 方法“numberOfRowsInSection”被触发,但没有方法“cellForRowAtIndexPath”...... ???

    在同样的问题上花了一天的时间后,我想我们在这里发现了一个错误。不过,我确实找到了破解/解决方法。

    如果我更改在我的 cellForRowAtIndexPath 方法中使用的数组(添加/删除值或完全重新构建它),它似乎在您重新加载数据时再次正确调用 cellForRowAtIndexPath。

    例如,在我的 cellForRowAtIndexPath 中,我有类似的内容:

    cell.textLabel.text = [[[self.searchResultsArrayWithSections objectAtIndex:indexPath.section] objectForKey:@"rowValues"] objectAtIndex:indexPath.row];
    
        return cell;
    

    我还有一个方法来构建这个在 viewDidLoad 上调用的数组:

        - (NSMutableArray *)splitIntoSectionsWithAlphabet:(NSMutableArray *)myArray 
    {    
    NSString *letters = @"abcdefghijklmnopqrstuvwxyz";
    NSMutableArray *content = [NSMutableArray new];
    
    //code to build array here, nothing special really
    
    return content;
    }
    

    所以我注意到,如果我在调用 reloadData 之前专门在我的 searchResultsArrayWithSections 数组上再次调用此方法,它实际上会正确调用所有 UITableViewDelegate 方法! (就像我说的,破解但它有效!)

    //dirty hack, bug with cancel button and not realoding data, seems we have to modify this array before it will work correctly
    self.customerListArrayWithSections = [self splitIntoSectionsWithAlphabet:self.customerListArray];
    [self.customerListTv reloadData];
    

    【讨论】:

      【解决方案3】:

      检查你的numberOfRows,如果是0,没有单元格可以显示。

      【讨论】:

        【解决方案4】:

        在我的例子中,问题是 reloadData() 函数不是从 主线程 调用的。

        我已经通过将它放在 dispatch_async() 函数中进行了更改,从而解决了问题:

        dispatch_async(dispatch_get_main_queue(), {
            self.tableView.reloadData()
        })
        

        希望这对其他人有所帮助。

        【讨论】:

          【解决方案5】:

          我有同样的问题,但决定很简单。 首先,您可以尝试向下滚动表格吗? tableView:cellForRow... 应该被调用。 检查 tableView 的标题高度和 contentOffset。

          【讨论】:

            【解决方案6】:

            您还可以在 viewController 的 init[With...] 方法中分配表,并在 IB 中连接相同的属性。这样,可能会调用 numberOf... 委托方法而 cellForRow... 不会。

            【讨论】:

              【解决方案7】:

              我的“AutoLayouted” UITableView 没有在 reloadData 上调用 cellForRowAtIndexPath,因为我错误地设置了框架。

              _tableView = [[UITableView alloc] initWithFrame:self.view.frame];
              _tableView.translatesAutoresizingMaskIntoConstraints = NO;
              

              通过将其更改为 CGRectZero,它起作用了..

              _tableView = [[UITableView alloc] initWithFrame:CGRectZero];
              _tableView.translatesAutoresizingMaskIntoConstraints = NO;
              

              【讨论】:

                猜你喜欢
                • 2013-12-30
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 2014-06-21
                • 1970-01-01
                相关资源
                最近更新 更多