UISearchController searchBar在按下viewcontroller时不会消失

我使用UISearchController里面包含一个UITableView UIViewcontroller ,我这样做viewDidLoad

  self.searchController = [[UISearchController alloc] initWithSearchResultsController:nil]; self.searchController.delegate = self; self.searchController.searchResultsUpdater = self; self.searchController.searchBar.delegate = self; self.searchController.dimsBackgroundDuringPresentation = NO; self.searchController.hidesNavigationBarDuringPresentation = NO; self.definesPresentationContext = NO; 

当我在导航栏中按下button时,我这样做:

  self.tableView.contentOffset = CGPointMake(0, 0 - self.tableView.contentInset.top); self.tableView.tableHeaderView = self.searchController.searchBar; [self.searchController.searchBar becomeFirstResponder]; 

所有工作正常,但是当我从UITableView结果行中推UIViewControllerUISearchBar呆在那里,也显示在另一个视图的内容,我怎么可以解雇,当我推视图,当我回去看到UITableView结果?

谢谢

编辑:

这是方法didSelectRowAtIndexPath的代码:

 - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { [self.tableView deselectRowAtIndexPath:indexPath animated:YES]; DetailListController *detailList = [[DetailListController alloc] init]; [self.navigationController pushViewController:detailList animated:YES]; } 

试试这个苹果build议的标准方式:

声明属性:

 @interface APLMainTableViewController () <UISearchBarDelegate, UISearchControllerDelegate, UISearchResultsUpdating> @property (nonatomic, strong) UISearchController *searchController; // our secondary search results table view @property (nonatomic, strong) APLResultsTableController *resultsTableController; // for state restoration @property BOOL searchControllerWasActive; @property BOOL searchControllerSearchFieldWasFirstResponder; @end - (void)viewDidLoad { [super viewDidLoad]; _resultsTableController = [[APLResultsTableController alloc] init]; _searchController = [[UISearchController alloc] initWithSearchResultsController:self.resultsTableController]; self.searchController.searchResultsUpdater = self; [self.searchController.searchBar sizeToFit]; self.tableView.tableHeaderView = self.searchController.searchBar; // we want to be the delegate for our filtered table so didSelectRowAtIndexPath is called for both tables self.resultsTableController.tableView.delegate = self; self.searchController.delegate = self; self.searchController.dimsBackgroundDuringPresentation = NO; // default is YES self.searchController.searchBar.delegate = self; // so we can monitor text changes + others // Search is now just presenting a view controller. As such, normal view controller // presentation semantics apply. Namely that presentation will walk up the view controller // hierarchy until it finds the root view controller or one that defines a presentation context. // self.definesPresentationContext = YES; // know where you want UISearchController to be displayed } - (void)viewDidAppear:(BOOL)animated { [super viewDidAppear:animated]; // restore the searchController's active state if (self.searchControllerWasActive) { self.searchController.active = self.searchControllerWasActive; _searchControllerWasActive = NO; if (self.searchControllerSearchFieldWasFirstResponder) { [self.searchController.searchBar becomeFirstResponder]; _searchControllerSearchFieldWasFirstResponder = NO; } } } #pragma mark - UISearchBarDelegate - (void)searchBarSearchButtonClicked:(UISearchBar *)searchBar { [searchBar resignFirstResponder]; } #pragma mark - UISearchControllerDelegate // Called after the search controller's search bar has agreed to begin editing or when // 'active' is set to YES. // If you choose not to present the controller yourself or do not implement this method, // a default presentation is performed on your behalf. // // Implement this method if the default presentation is not adequate for your purposes. // - (void)presentSearchController:(UISearchController *)searchController { } - (void)willPresentSearchController:(UISearchController *)searchController { // do something before the search controller is presented } - (void)didPresentSearchController:(UISearchController *)searchController { // do something after the search controller is presented } - (void)willDismissSearchController:(UISearchController *)searchController { // do something before the search controller is dismissed } - (void)didDismissSearchController:(UISearchController *)searchController { // do something after the search controller is dismissed } 

这里有一个有趣的部分:使用下面的代码来恢复从详细视图回来的状态

 #pragma mark - UIStateRestoration // we restore several items for state restoration: // 1) Search controller's active state, // 2) search text, // 3) first responder NSString *const ViewControllerTitleKey = @"ViewControllerTitleKey"; NSString *const SearchControllerIsActiveKey = @"SearchControllerIsActiveKey"; NSString *const SearchBarTextKey = @"SearchBarTextKey"; NSString *const SearchBarIsFirstResponderKey = @"SearchBarIsFirstResponderKey"; - (void)encodeRestorableStateWithCoder:(NSCoder *)coder { [super encodeRestorableStateWithCoder:coder]; // encode the view state so it can be restored later // encode the title [coder encodeObject:self.title forKey:ViewControllerTitleKey]; UISearchController *searchController = self.searchController; // encode the search controller's active state BOOL searchDisplayControllerIsActive = searchController.isActive; [coder encodeBool:searchDisplayControllerIsActive forKey:SearchControllerIsActiveKey]; // encode the first responser status if (searchDisplayControllerIsActive) { [coder encodeBool:[searchController.searchBar isFirstResponder] forKey:SearchBarIsFirstResponderKey]; } // encode the search bar text [coder encodeObject:searchController.searchBar.text forKey:SearchBarTextKey]; } - (void)decodeRestorableStateWithCoder:(NSCoder *)coder { [super decodeRestorableStateWithCoder:coder]; // restore the title self.title = [coder decodeObjectForKey:ViewControllerTitleKey]; // restore the active state: // we can't make the searchController active here since it's not part of the view // hierarchy yet, instead we do it in viewWillAppear // _searchControllerWasActive = [coder decodeBoolForKey:SearchControllerIsActiveKey]; // restore the first responder status: // we can't make the searchController first responder here since it's not part of the view // hierarchy yet, instead we do it in viewWillAppear // _searchControllerSearchFieldWasFirstResponder = [coder decodeBoolForKey:SearchBarIsFirstResponderKey]; // restore the text in the search field self.searchController.searchBar.text = [coder decodeObjectForKey:SearchBarTextKey]; } @end 

当您从DetailListController到您的视图控制器(为了安全性封装在主线程中)时,您需要调用它:

 dispatch_async(dispatch_get_main_queue(), ^{ self.searchController.active = NO; }); 

你也可以在viewWillDisappear:调用它viewWillDisappear:当前的视图控制器。

把这个代码放在你的viewDidLoad

 self.definesPresentationContext = YES; 

在试图处理同样的问题几天后,意识到这样做的正确方法是让一个导航控制器包含search层次结构中的所有内容

喜欢这个 :

  • 导航1(无导航栏)
  • (….标签栏,别的…)
  • 导航2(有导航栏,此导航栏被search栏取代
  • 表控制器

当你推细节控制器时,将其推入导航栏1,同时显示其导航栏。

这样可以使search堆栈保持原样,并在您点击详细信息页面上的“返回”时准备就绪