Ich habe versucht, einem TableViewController in meiner App einfache Suchfunktionen hinzuzufügen. Ich folgte Ray Wenderlichs Tutorial. Ich habe eine Tabellenansicht mit einigen Daten, ich habe die Suchleiste + den Display-Controller im Storyboard hinzugefügt und dann habe ich diesen Code:
#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;
}
Das Standardmaterial, aber wenn ich Text in die Suchleiste eingebe, stürzt es jedes Mal mit diesem Fehler ab:
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'
Ich verstehe, dass sich in iOS 6 das Handhabungs- und Warteschlangensystem für Zellen geändert hat und dass bei der Suche eine andere Tabellenansicht verwendet wird. Daher dachte ich, dass das Problem darin bestand, dass die Suchtabellenansicht mit den gefilterten Ergebnissen nichts über die Zelle wusste dies in meiner viewDidLoad:
[self.searchDisplayController.searchResultsTableView registerClass:[UITableViewCell class] forCellReuseIdentifier:@"BreedCell"];
Und voila! Es hat funktioniert ... Nur beim ersten Suchen. Wenn Sie zu den ursprünglichen Ergebnissen zurückkehren und erneut suchen, stürzt die App mit demselben Fehler ab. Ich dachte darüber nach, vielleicht alles hinzuzufügen
if(!cell){//init cell here};
Zeug zur cellForRow-Methode, aber widerspricht das nicht dem ganzen Zweck, die dequeueReusableCellWithIdentifier: forIndexPath: -Methode zu haben? Wie auch immer, ich bin verloren. Was vermisse ich? Hilfe bitte. Vielen Dank im Voraus für all Ihre Zeit (:
Alex.
dequeueReusableCellWithIdentifier:forIndexPath:
durchdequeueReusableCellWithIdentifier:
.Der Grund, warum es beim ersten Start hervorragend funktioniert hat, dann aber abgestürzt ist, wenn Sie die Ergebnistabelle verlassen und erneut gesucht haben, liegt darin, dass der Search Display Controller
UITableView
jedes Mal, wenn Sie in den Suchmodus wechseln, eine neue lädt .Mit Suchmodus meine ich, Sie haben auf das Textfeld getippt und mit der Eingabe begonnen. Zu diesem Zeitpunkt wird eine Tabellenansicht generiert, um die Ergebnisse anzuzeigen. Sie verlassen diesen Modus, indem Sie auf die Schaltfläche Abbrechen klicken. Wenn Sie das zweite Mal auf das Textfeld tippen und erneut mit der Eingabe beginnen, wird der Suchmodus zum zweiten Mal aufgerufen.
Um den Absturz zu vermeiden, sollten Sie die Zellenklasse für die Tabellenansicht registrieren, die in der
searchDisplayController:didLoadSearchResultsTableView:
Delegate-Methode (vonUISearchDisplayDelegate
) anstelle der Controller-viewDidLoad
Methode verwendet werden soll.Wie folgt:
Das hat mich überrascht, weil unter iOS 7 ... die Tabellenansicht wiederverwendet wird. Sie können die Klasse also anmelden,
viewDidLoad
wenn Sie dies bevorzugen. Aus Gründen des Vermächtnisses behalte ich meine Registrierung in der von mir erwähnten Delegatenmethode.quelle
Nach der Suche scheint 'tableView' der cellForRowAtIndexPath-Methode keine Instanz der von Ihnen definierten Tabelle zu sein. Sie können also eine Instanz einer Tabelle verwenden, die die Zelle definiert. Anstatt:
Verwenden:
(Verwenden Sie nicht die tableView der cellForRowAtIndexPath-Methode, sondern self.tableView .)
quelle
Deaktivieren Sie die Zelle, ohne den 'indexPath' zu verwenden. Wenn Sie ein Null-Element erhalten, müssen Sie es manuell zuweisen.
Der Versuch, self.tableView zum Löschen der Zelle zu verwenden, kann zu Abstürzen führen, wenn Sie eine unterteilte Hauptliste und eine einfache Suchliste haben. Dieser Code funktioniert stattdessen in jeder Situation.
quelle
Als ich dieses Problem hatte, ersetzte die Lösung
tableView
dequeueReusableCellWithIdentifier: @yourcell durchself.tableView
quelle
Ich arbeite auch an diesem Tutorial. Der Standard-TableViewController hat "forIndexPath" und in seinem Beispiel existiert er nicht. Sobald ich es entfernt habe, funktioniert die Suche.
quelle
Für Swift 3 müssen Sie nur sich selbst hinzufügen:
quelle