在UITableViewController中使用UISearchDisplayController时声明失败
我一直在尝试添加简单的searchfunction到我的应用程序中的TableViewController。 我跟随了Ray Wenderlich的教程。 我有一个tableView与一些数据,我添加了故事板中的search栏+显示控制器,然后我有这样的代码:
#pragma mark - Table View - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{ UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"BreedCell" forIndexPath:indexPath]; //Create PetBreed Object and return corresponding breed from corresponding array PetBreed *petBreed = nil; if(tableView == self.searchDisplayController.searchResultsTableView) petBreed = [_filteredBreedsArray objectAtIndex:indexPath.row]; else petBreed = [_breedsArray objectAtIndex:indexPath.row]; cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator; cell.textLabel.text = petBreed.name; return cell; } #pragma mark - Search -(BOOL)searchDisplayController:(UISearchDisplayController *)controller shouldReloadTableForSearchString:(NSString *)searchString { [_filteredBreedsArray removeAllObjects]; NSPredicate *predicate = [NSPredicate predicateWithFormat:@"SELF.name contains[c] %@",searchString]; _filteredBreedsArray = [[_breedsArray filteredArrayUsingPredicate:predicate] mutableCopy]; return YES; } -(BOOL)searchDisplayController:(UISearchDisplayController *)controller shouldReloadTableForSearchScope:(NSInteger)searchOption { // Tells the table data source to reload when scope bar selection changes [_filteredBreedsArray removeAllObjects]; NSPredicate *predicate = [NSPredicate predicateWithFormat:@"SELF.name contains[c] %@",self.searchDisplayController.searchBar.text]; _filteredBreedsArray = [[_breedsArray filteredArrayUsingPredicate:predicate] mutableCopy]; return YES; }
标准的东西,但是当我在search栏中input文本时,每次都会出现这个错误:
2013-01-07 19:47:07.330 FindFeedo[3206:c07] *** Assertion failure in -[UISearchResultsTableView dequeueReusableCellWithIdentifier:forIndexPath:], /SourceCache/UIKit_Sim/UIKit-2372/UITableView.m:4460 2013-01-07 19:47:07.330 FindFeedo[3206:c07] *** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'unable to dequeue a cell with identifier BreedCell - must register a nib or a class for the identifier or connect a prototype cell in a storyboard'
我知道在iOS 6中,单元格的处理和出队系统发生了变化,并且search使用了不同的tableView,所以我认为问题在于searchtableView和过滤结果不知道单元格,所以我把这在我的viewDidLoad:
[self.searchDisplayController.searchResultsTableView registerClass:[UITableViewCell class] forCellReuseIdentifier:@"BreedCell"];
瞧! 它的工作…只有你第一次search。 如果你回到原来的结果并再次search,该应用程序崩溃与相同的错误。 我想也许加上所有的
if(!cell){//init cell here};
东西的cellForRow方法,但是这不符合具有dequeueReusableCellWithIdentifier:forIndexPath:方法的整个目的? 无论如何,我迷路了。 我错过了什么? 请帮助。 所有的时间提前谢谢你(:
亚历克斯。
尝试在dequeueReusableCellWithIdentifier中使用self.tableView而不是tableView:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{ UITableViewCell *cell = [self.tableView dequeueReusableCellWithIdentifier:@"BreedCell"]; //Create PetBreed Object and return corresponding breed from corresponding array PetBreed *petBreed = nil; if(tableView == self.searchDisplayController.searchResultsTableView) petBreed = [_filteredBreedsArray objectAtIndex:indexPath.row]; else petBreed = [_breedsArray objectAtIndex:indexPath.row]; cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator; cell.textLabel.text = petBreed.name; return cell; }
这段代码工作得很好
注意
如果您有自定义高度单元格,请勿使用
[self.tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
改用这个
[self.tableView dequeueReusableCellWithIdentifier:CellIdentifier];
之所以在第一次运行时效果很好,但是如果退出结果表并返回进行其他search,则会崩溃,因为每次进入search模式时,search显示控制器都会加载一个新的UITableView
。
通过search模式我的意思是,你已经点击了文本框,你已经开始键入,在这一点上生成一个表视图来显示结果,退出这个模式,通过点击取消button。 当您第二次点击文本字段并再次input时 – 这是第二次进入“search模式”。
因此,为了避免崩溃,您应该registry视图的单元类,以在searchDisplayController:didLoadSearchResultsTableView:
delegate方法(来自UISearchDisplayDelegate
)中使用,而不是在您的控制器的viewDidLoad
方法中使用。
如下:
- (void)searchDisplayController:(UISearchDisplayController *)controller didLoadSearchResultsTableView:(UITableView *)tableView { [tableView registerClass:[DPContentTableCell class] forCellReuseIdentifier:cellIdentifier]; [tableView registerClass:[DPEmptyContentTableCell class] forCellReuseIdentifier:emptyCellIdentifier]; }
这令我吃惊,因为在iOS 7上…表视图正在被重用。 所以你可以在viewDidLoad
注册这个类。 对于遗留的问题,我将使用我提到的委托方法保留我的注册。
search后,cellForRowAtIndexPath方法的'tableView'似乎不是您定义的表的一个实例。 所以,你可以使用定义单元格的表格的一个实例。 代替:
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"Cell" forIndexPath:indexPath];
使用:
UITableViewCell *cell = [self.tableView dequeueReusableCellWithIdentifier:@"Cell" forIndexPath:indexPath];
(不要使用cellForRowAtIndexPath方法的tableView ,使用self.tableView 。)
在不使用'indexPath'的情况下退出单元格,如果获得nil元素,则必须手动分配它。
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"YourCellId"]; if (!cell) cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"YourCellId"]; // fill your cell object with useful stuff :) return cell; }
尝试使用self.tableView来出列单元格可能会导致崩溃,当您有一个分区的主列表和普通的search列表。 这个代码可以在任何情况下工作。
当我有这个问题,解决scheme是取代tableView
dequeueReusableCellWithIdentifier:@yourcell与self.tableView
我正在研究这个教程。 默认的TableViewController有“forIndexPath”,在他的例子中它不存在。 一旦我删除它的search工作。
//Default code UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath]; //Replace with UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
对于swift 3,你只需要添加自己:
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { let cell = self.tableView.dequeueReusableCell(withIdentifier: "yourCell", for: indexPath) as! YourCell ... }
- 在unit testing中重复代码更容易?
- xcrun:错误:不能stat激活Xcodepath'/Volumes/Xcode/Xcode45-DP1.app/Contents/Developer'。 (无此文件或目录)
- 从NSString NSJSONSerialization
- 如何使用drawInRect:withAttributes:而不是drawAtPoint:forWidth:withFont:fontSize:lineBreakMode:baselineAdjustment:in iOS 7
- 检测应用程序是否从推送通知启动/打开
- 将图像保存到文档目录并检索电子邮件附件
- 如何在执行API时避免在块中捕获自己?
- 将“清除”button添加到iPhone UITextField
- AVPlayer和Video的截图
- 如何在Swift中使用SCNetworkReachability
- 我如何生成一个iOS版本构build,我的客户端可以签署他们的最终?