2011-11-09 12 views
24

Implementuję UITableView z UISearchDisplayController w kodzie Xcode 4.2. UITableView & UISearchDisplayController są tworzone w StoryBoard. ustawić identyfikator komórki (SampleCell) dla UITableView i dostęp to jakUsterka iOS 5 UISearchDisplayController crash

cell = [tableView dequeueReusableCellWithIdentifier:@"SampleCell"]; 

UITableView działa poprawnie. Ale gdy próbuję szukać, awarie aplikacji poniżej błędu.

*** Assertion failure in -[UISearchResultsTableView _createPreparedCellForGlobalRow:withIndexPath:], /SourceCache/UIKit_Sim/UIKit-1912.3/UITableView.m:6072 
2011-11-09 22:22:16.058 SampleApp[14362:fb03] *** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'UITableView dataSource must return a cell from tableView:cellForRowAtIndexPath:' 

Chyba trzeba ustawić identyfikator komórki na komórkę self.searchDisplayController.searchResultsTableView. Ale nie wiem jak. Z góry dziękuję za pomoc. =)

+0

+1 dla uratowałeś mi czasu na wpisywanie question.I dokładny obliczu problemu sam. – thesummersign

Odpowiedz

16

Naprawdę trudny do śledzenia, wydaje się, że za każdym razem, gdy wykonujesz wyszukiwanie, tworzony jest nowy widok tabeli. Oznacza to, że rejestracja twojej komórki musi zostać usunięta z ViewDidLoad, ponieważ działa to tylko przy pierwszym wyszukiwaniu. Zamiast użyć następującej metody delegata zrobić rejestrowanie komórek i dostosowanie:

- (void)searchDisplayControllerWillBeginSearch:(UISearchDisplayController *)controller 
{ 
    [self.searchDisplayController.searchResultsTableView 
    registerNib:[UINib nibWithNibName:@"YOURCELLNIB" bundle:nil] forCellReuseIdentifier:@"YOURCELLID"]; 
    self.searchDisplayController.searchResultsTableView.separatorColor = [UIColor clearColor]; 
} 
+0

+1.Miałem do czynienia z bardzo podobnym problemem i odkryłem, że po usunięciu wszystkich połączeń z rejestracjąNib i zastąpieniu ich inną metodą ładowania komórek wszystko działało dobrze. –

+0

Czy wiesz, jak radzić sobie z jego ios5 z stoaryboards? Stworzyłem własną komórkę, która rozszerza UITableView i wybrał styl niestandardowy w scenorysie. Wszystko działa poprawnie, ale podczas filtrowania tablview komórka w komórceforrowatindexpath jest zawsze zerowa, więc pojawia się błąd: oprócz powyższego widoku widzę *** Aplikacja kończąca z powodu nieprzechwyconego wyjątku "NSInternalInconsistencyException", powód: "UITableView dataSource musi zwracać komórka z tableView: cellForRowAtIndexPath. Jak programowo utworzyć niestandardową komórkę, którą utworzyłem w moim programie tematycznym? – imrank1

+0

Dziękuję, dziękuję, dziękuję !!! To doprowadzało mnie do szału, ponieważ musiałem koniecznie zarejestrować stalówkę dla komórek searchResultsTableView, a umieszczenie kodu w viewDidLoad było wyraźnie błędne. Gdybym mógł powtórzyć twoją odpowiedź, zrobiłbym to! –

83

Korzystając [self.tableView dequeue...] nie [tableView dequeue...].

Ogniwo próbujesz dequeue jest związany z podstawową kontroler widok na tableView w serii ujęć, a nie searchDisplayController „s nowo utworzony tableView (który nie ma identyfikatorów komórek powiązanych z nim). Jeśli wyświetli się komunikat "tableView", wówczas wiadomość o usunięciu kolejki przechodzi do tabeli searchDisplayController's tableview, ponieważ została ona przekazana do metody cellForRowAtIndexPath: ....

-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 
{ 
    UITableViewCell *cell = [self.tableView dequeueReusableCellWithIdentifier:@"CellId"]; 

    // do your thing 

    return cell; 
} 
+0

działa jak czar !! Dziękuję bardzo! – Anthony

+11

(+1) odpowiedź powinna zostać przyjęta. – thesummersign

+0

Nowym problemem jest to, że wynik wyszukiwania jest ładowany do popover, który nie jest pożądany. czy mogę w jakiś sposób użyć własnego ('self.tableView') do wyświetlania wyników wyszukiwania? – thesummersign

10

(Odpowiedź który zaleca stosowanie self.tableview jest zależny od innego widoku tabeli. Jest to najczystsze rozwiązanie i może być stosowany nawet jeśli kontroler wyszukiwania jest stosowany sam.)

Ty trzeba zarejestrować komórki w UITableView UISearchDisplayController. Najlepszym sposobem na to jest zarejestrowanie komórek po załadowaniu widoku tabeli.

Metoda UISearchDisplayDelegate zawiera metodę powiadamiającą o załadowaniu widoku tabeli - podobnie jak viewDidLoad, ale dla widoku tabeli wyszukiwania.

- (void)searchDisplayController:(UISearchDisplayController *)controller didLoadSearchResultsTableView:(UITableView *)tableView 
{ 
    [tableView registerNib:[UINib nibWithNibName:@"MyCellNib" bundle:[NSBundle mainBundle]] forCellReuseIdentifier:@"MyCellIdentifier"]; 
} 
+0

To zdecydowanie najlepsze rozwiązanie, aby uniknąć awarii po pierwszym załadowaniu! To znaczy, jeśli po prostu odfiltrowałeś już pobrane dane, to w przeciwnym razie działałoby to zgodnie z oczekiwaniami. Ale jeśli ktoś powinien móc wykonywać ** zdalne wyszukiwania **, widok tabeli kontrolnej searchcontroller powinien wyraźnie nie być zależny od oryginalnego widoku tabeli. – Hulvej

+2

Bardzo pomocny. Zobacz także: 'registerClass: forCellReuseIdentifier:' jeśli twoje komórki są zdefiniowane w kodzie zamiast Konstruktora interfejsu. – Nick

0

Można w

- (void)searchDisplayController:(UISearchDisplayController *)searchDisplayController didLoadSearchResultsTableView:(UITableView *)searchResultsTableView

zrobić

[searchResultsTableView registerNib:[UINib nibWithNibName:@"someNibName" bundle:nil] forCellReuseIdentifier:@"yourReuseId"];

Wtedy jesteś w stanie wykorzystać w

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {

normalny

[tableView dequeueReusableCellWithIdentifier: