UITableView reloadData - cellForRowAtIndexPath 未触发
Posted
技术标签:
【中文标题】UITableView reloadData - cellForRowAtIndexPath 未触发【英文标题】:UITableView reloadData - cellForRowAtIndexPath not fired 【发布时间】: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”...... ???
谢谢
【问题讨论】:
【参考方案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;
【讨论】:
以上是关于UITableView reloadData - cellForRowAtIndexPath 未触发的主要内容,如果未能解决你的问题,请参考以下文章
UITableView.reloadData() 没有刷新 tableView。没有错误信息
UITableView 的 reloadData() 的替代方案?
UIView 与 UITableview 和 UIImageview,使用 reloadData 访问 UITableview
UITableView 强制 sectionIndex 更新而不调用 reloadData