2011-11-09 114 views
24

我正在xcode 4.2中使用UISearchDisplayController實現UITableView。 UITableView & UISearchDisplayController在StoryBoard中創建。 我設置的UITableView小區標識符(SampleCell)和訪問它像ios 5 UISearchDisplayController崩潰

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

UITableView的是工作的罰款。 但是,一旦我嘗試搜索,應用程序崩潰與下面的錯誤。

*** 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:' 

我想我需要設置self.searchDisplayController.searchResultsTableView單元格的單元格標識符。 但我不知道如何。 在此先感謝您的幫助。 =)

+0

+1你救了我的時間,鍵入question.I確切面臨SAM問題。 – thesummersign

回答

16

確實存在嚴重的錯誤,似乎每次搜索時都會創建一個新的tableview。這意味着你的單元註冊必須從ViewDidLoad中取出,因爲這隻適用於第一次搜索。相反,使用下面的委託方法做細胞登記和定製:

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

+1。我正在處理一個非常類似的問題,並發現一旦我刪除了所有對registerNib的調用,並用一種​​不同的方法加載單元格,一切正常。 –

+0

你知道如何用stoaryboards處理他的ios5嗎?我創建了自己的單元格,它擴展了UITableView並在故事板中選擇了自定義樣式。一切正常,但過濾tablview cellforrowatindexpath中的單元格總是爲零,所以我得到的錯誤:除了上面的錯誤,我看到終止應用程序由於未捕獲的異常'NSInternalInconsistencyException',原因:'UITableView數據源必須返回一個來自tableView:cellForRowAtIndexPath的單元格。如何創建我的故事板以編程方式創建的自定義單元格? – imrank1

+0

謝謝,謝謝,謝謝!這讓我瘋狂,因爲我必須爲searchResultsTableView單元註冊一個筆尖,並將代碼放在viewDidLoad中顯然是錯誤的。如果我能再次提出你的答案,我會這樣做! –

83

使用[self.tableView dequeue...],不[tableView dequeue...]

你想離隊的單元格鏈接到您的主視圖控制器的tableView在故事板,而不是searchDisplayController的新創建tableView(其中有鏈接到它沒有細胞識別)。如果您只是發送「tableView」消息,那麼您的出隊消息將轉到searchDisplayController's tableView,因爲這是傳入cellForRowAtIndexPath: ...方法的內容。

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

    // do your thing 

    return cell; 
} 
+0

工程就像一個魅力!非常感謝! – Anthony

+11

(+1)答案應該被接受。 – thesummersign

+0

新問題是搜索結果被加載到不需要的彈出窗口中。我可以以某種方式使用我自己的('self.tableView')來顯示搜索結果嗎? – thesummersign

10

(即建議使用self.tableview答案是依賴於另一個表視圖。這是乾淨的解決方案,並且如果搜索控制器用於通過本身甚至可以使用。)

您需要在UISearchDisplayController的UITableView上註冊這些單元格。最好的辦法是在加載表格視圖時註冊單元格。

UISearchDisplayDelegate有一個方法,可以在加載表視圖時通知您 - 就像viewDidLoad一樣,但是用於搜索表視圖。

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

這是迄今爲止在第一次加載後避免碰撞的最佳解決方案! 我的意思是,如果你只是過濾出_already_提取的數據,另一種方式會按預期工作。但是,如果應該能夠執行**遠程搜索**,則searchcontroller表視圖應該明顯不依賴於原始表視圖。 – Hulvej

+2

非常有幫助。另見:'registerClass:forCellReuseIdentifier:'如果你的單元是在代碼而不是Interface Builder中定義的。 – Nick

0

你可以在

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

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

然後,你可以在使用

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

正常

[tableView dequeueReusableCellWithIdentifier: