在推送视图上使用 UISearchController

Using UISearchController on a pushed view

我已经在我的应用程序中成功实现了 UISearchController。我在视图的 viewDidLoad 方法中这样设置我想在其中使用它:

_profileSearchView = [self.storyboard instantiateViewControllerWithIdentifier:@"profileListView"];
[_profileSearchView initSearchController];
self.navigationItem.titleView = _profileSearchView.searchController.searchBar;

initSearchController 方法初始化搜索控制器,它是 _profileSearchView 的 属性,驻留在 _profileSearchView:

- (void) initSearchController {
    _searchController = [[UISearchController alloc] initWithSearchResultsController:self];
    _searchController.delegate = self;
    _searchController.hidesNavigationBarDuringPresentation = NO;

    _searchController.searchBar.delegate = self;
    _searchController.searchBar.searchBarStyle = UISearchBarStyleMinimal;
    _searchController.searchBar.showsCancelButton = YES;
    _searchController.searchBar.frame = CGRectMake(self.searchController.searchBar.frame.origin.x, self.searchController.searchBar.frame.origin.y, self.searchController.searchBar.frame.size.width, 44.0);
}

如果我在导航控制器的根视图中使用它,效果很好。但是如果我推送一个视图并尝试在那里使用它,搜索控制器不会变为活动状态并且此错误会显示在控制台中:

Warning: Attempt to present <UISearchController: 0x7fb113605220> on <RootViewController: 0x7fb11318a6d0> whose view is not in the window hierarchy!

它抱怨的 RootViewController 是我从中推送的根视图。为什么这只适用于根视图?

更新:根视图控制器有self.definesPresentationContext = YES;(推送视图也有),当我从根视图中删除它时,搜索控制器工作在推送视图上。不幸的是,这也破坏了其他一些东西,所以我需要把它留在里面。那么我怎样才能让根视图和推送视图都有一个单独的功能搜索控制器?

由于您需要在初始化中访问一些视图框架信息,因此您需要将该初始化(或其中的一部分)移动到 viewWillAppear 以准备显示所有视图。在 ViewdidLoad 中,视图仅加载到内存中,因此您无法获取框架属性。

viewdidLoad:

_profileSearchView = [self.storyboard instantiateViewControllerWithIdentifier:@"profileListView"];

viewWillAppear:

[_profileSearchView initSearchController];
self.navigationItem.titleView = _profileSearchView.searchController.searchBar;

问题是由根视图和推送视图都具有 self.definesPresentationContext = YES; 引起的。解决方案是添加:

- (void) viewWillDisappear:(BOOL)animated {
    [super viewWillDisappear:animated];
    self.definesPresentationContext = NO;
}

并确保视图出现时 YES:

-(void) viewWillAppear:(BOOL)animated {
    self.definesPresentationContext = YES;
}

在根视图中。根视图仍然能够从其自己的搜索控制器正确推送搜索结果,推送视图也是如此。

来自Apple Documentation

Instance Property

definesPresentationContext

A Boolean value that indicates whether this view controller's view is covered when the view controller or one of its descendants presents a view controller.

当您推送新的控制器视图时,将此 属性 设置为 false。这个节目解决你的问题。

Ps。当旧视图控制器再次可见时,请记住再次支持 属性 true。