2016-07-27 38 views
11

我有一個表視圖控制器UISearchController設置UISearchBartableView.tableHeaderView。更新搜索結果時,我使用beginUpdatesendUpdates及相關方法更新表視圖的數據。當使用beginUpdates/endUpdates時,UISearchBar從tableHeaderView消失

這使搜索欄消失; tableHeaderView被設置爲與搜索欄大小相同的空的通用UIView。如果我只是使用reloadData而不是整個beginUpdates/endUpdates程序,一切都很好。

表視圖控制器嵌入在常規的視圖控制器;沒有涉及導航控制器。這是必要的表視圖控制器的整個執行重現該問題:

- (void)viewDidLoad 
{ 
    [super viewDidLoad]; 

    self.searchController = [[UISearchController alloc] initWithSearchResultsController:nil]; 
    self.searchController.searchResultsUpdater = self; 
    self.searchController.dimsBackgroundDuringPresentation = NO; 

    self.tableView.tableHeaderView = self.searchController.searchBar; 
} 

- (void)updateSearchResultsForSearchController:(UISearchController *)searchController 
{ 
    [self.tableView beginUpdates]; 
    [self.tableView endUpdates]; 
} 

爲什麼這會導致搜索欄與空白視圖代替,並且怎麼能避免?

+0

您是否嘗試更改viewController/Navigation控制器上的「半透明」屬性?我記得我曾經有過這個問題,如果我記得正確的「半透明」,它與它有關。 – MCMatan

回答

0

當您第一次點擊UISearchController's searchBar時,searchBar需要大約0.5秒的動畫時間。但self.tableView.endUpdates()被委託方法立即調用,動畫被中斷。
搜索欄停留在動畫中,你不能看到它的UI:
enter image description here

一種解決方法是檢查是否搜索欄是動畫,延緩self.tableView.endUpdates()當它在不在。

func updateSearchResultsForSearchController(searchController: UISearchController){ 
    self.tableView.beginUpdates() 
    //Do some updates 

    if !searchController.searchBar.showsCancelButton{ 
     self.tableView.performSelector(#selector(UITableView.endUpdates), withObject: nil, afterDelay: 1) 

    }else{ 
     self.tableView.endUpdates() 
    } 
} 
+0

謝謝你的回答。我認爲你正在談論動畫。我曾嘗試像[CATransaction setCompletionBlock:]這樣的技巧,但無濟於事。你的解決方法似乎特別黑,而且對原始問題不起作用。可能是因爲它不像我提供的可重複的例子那樣人爲設計,並且在'beginUpdates'和'endUpdates'之間做了更多的工作。 –

+0

在這種情況下,您應該嘗試使用另一個tableViewController來初始化您的'UISearchController',並使用第二個tableViewController執行所有更新。 – wj2061

+0

正如'[[UISearchController alloc] initWithSearchResultsController:...]'?我想這是一個解決方案,但我想保留與原始表格視圖相關的所有功能,例如手勢等。如果沒有其他方法,那麼重構無法解決什麼問題。 –

0

小改版約beginUpdates, endUpdates and reloadData

beginUpdates::開始的一系列方法的調用插入,刪除,或選擇行和表視圖的部分。 如果您希望後續插入,刪除和選擇操作(例如cellForRowAtIndexPath:和indexPathsForVisibleRows)同時進行動畫,請調用此方法。您也可以使用此方法,然後使用endUpdates方法在不重新加載單元格的情況下對行高的更改進行動畫處理。這組方法必須以endUpdates的調用結束。這些方法對可以嵌套。如果您不在該塊內進行插入,刪除和選擇調用,則表格屬性(如行計數)可能會失效。你不應該在組中調用reloadData;如果您在組中調用此方法,則必須自己執行任何動畫。

endUpdates:結束了一系列插入,刪除,選擇或重新加載表視圖的行和部分的方法調用。 您可以調用此方法以包圍以beginUpdates開頭的一系列方法調用,該方法調用由插入,刪除,選擇和重新加載表視圖的行和部分的操作組成。當您調用endUpdates時,UITableView將同時爲這些操作提供動畫。 beginUpdates和endUpdates的調用可以嵌套。如果不在該塊內進行插入,刪除和選擇調用,則諸如行計數之類的表屬性可能會失效。

reloadData:重新加載表視圖的行和部分。 調用此方法重新加載用於構造表的所有數據,包括單元格,節標題和頁腳,索引數組等。爲了提高效率,表格視圖僅重新顯示那些可見的行。如果表格由於重新加載而縮小,它會調整偏移量。表視圖的委託或數據源在希望表視圖完全重新加載其數據時調用此方法。不應在插入或刪除行的方法中調用,特別是在調用beginUpdates和endUpdates所實現的動畫塊中。

現在搜索的情況下,我們不知道是哪個行會影響以及每次搜索結果的數據會有所不同,我認爲不應該使用

[self.tableView beginUpdates]; 
[self.tableView endUpdates]; 

其使用時,你正在對tableview執行insert, update or delete操作,並且您知道它的indexPath

更好地使用[self.tableView reloadData];,因爲它只會更新tableview中的可見行或節。另請參閱Apple的示例代碼Table Search with UISearchController,它也推薦使用reloadData

進行相應的更改,你很好去。

快樂編碼:)

+0

我知道使用'reloadData'會使問題消失,儘管這並不能解釋爲什麼不能使用'beginUpdates'和'endUpdates'。 –

+0

@Håvard多數民衆贊成在我已經解釋,什麼時候使用'beginUpdates和endUpdates'和'reloadData'。 –

相關問題