每当用户开始编辑UISearchDisplayController
的搜索栏时,搜索控制器将变为活动状态,并在显示搜索表视图时隐藏视图的导航栏。是否可以阻止UISearchDisplayController
隐藏导航栏而不重新实现它?
答案 0 :(得分:60)
我刚刚调试了一下UISearchDisplayController并发现它正在调用UINavigationController上的私有方法来隐藏导航栏。这发生在-setActive:animated:。如果您继承UISearchDisplayController并使用以下代码覆盖此方法,则可以通过伪造将其隐藏来阻止navigationBar被隐藏。
- (void)setActive:(BOOL)visible animated:(BOOL)animated;
{
if(self.active == visible) return;
[self.searchContentsController.navigationController setNavigationBarHidden:YES animated:NO];
[super setActive:visible animated:animated];
[self.searchContentsController.navigationController setNavigationBarHidden:NO animated:NO];
if (visible) {
[self.searchBar becomeFirstResponder];
} else {
[self.searchBar resignFirstResponder];
}
}
如果这对您有用,请告诉我。我也希望在未来的iOS版本中不会破坏...仅在iOS 4.0上测试。
答案 1 :(得分:52)
最简单的解决方案,没有黑客攻击。
@interface MySearchDisplayController : UISearchDisplayController
@end
@implementation MySearchDisplayController
- (void)setActive:(BOOL)visible animated:(BOOL)animated
{
[super setActive: visible animated: animated];
[self.searchContentsController.navigationController setNavigationBarHidden: NO animated: NO];
}
@end
答案 2 :(得分:46)
iOS 8中引入的新UISearchController
类具有属性hidesNavigationBarDuringPresentation
,如果要保持导航栏可见(默认情况下它仍然会被隐藏),您可以将其设置为false。
答案 3 :(得分:28)
上述答案对我来说并不合适。我的解决方案是欺骗UISearchDisplayController认为没有UINavigationController。
在视图控制器中,添加此方法
- (UINavigationController *)navigationController {
return nil;
}
这对我来说没有任何副作用,尽管看起来真的很糟糕......如果你需要进入导航控制器,请使用[super navigationController]
。
答案 4 :(得分:10)
从iOS 8.0开始,通过将UISearchController
的{{1}}属性设置为false,可以实现相同的行为。
Swift中的代码如下所示:
self.searchController.hidesNavigationBarDuringPresentation
答案 5 :(得分:9)
尝试不同的方式,没有子类化UISearchDisplayController。在你为UISearchDisplayController设置委托的UIViewController类中,实现searchDisplayControllerDidBeginSearch:并添加使用
[self.navigationController setNavigationBarHidden:NO animated:YES];
对我而言,希望有所帮助。
答案 6 :(得分:4)
我遇到了一个稍微不同的问题。使用UISearchDisplayController时,我希望搜索栏在的导航栏中(不在下面)
。将搜索栏放在导航栏中并不困难(请参阅UISearchBar and UINavigationItem)。但是,UISearchDisplayController假定搜索栏始终位于导航栏下方(如此处所述),在进入搜索时坚持隐藏导航栏,因此看起来很糟糕。此外,UISearchDisplayController使搜索栏比正常情况更轻。
我找到了解决方案。诀窍是(反直觉地)解开UISearchDisplayController根本不控制任何UISearchBar。如果使用xibs,这意味着删除搜索栏实例,或至少取消插座。然后创建自己的UISearchBar:
- (void)viewDidLoad
{
[super viewDidLoad];
UISearchBar *searchBar = [[[UISearchBar alloc] init] autorelease];
[searchBar sizeToFit]; // standard size
searchBar.delegate = self;
// Add search bar to navigation bar
self.navigationItem.titleView = searchBar;
}
当用户点击搜索栏(-searchBarShouldBeginEditing:
)时,您需要手动激活搜索显示控制器,并在用户结束搜索时手动关闭搜索栏(在-searchDisplayControllerWillEndSearch:
中)。
#pragma mark <UISearchBarDelegate>
- (BOOL)searchBarShouldBeginEditing:(UISearchBar *)searchBar {
// Manually activate search mode
// Use animated=NO so we'll be able to immediately un-hide it again
[self.searchDisplayController setActive:YES animated:NO];
// Hand over control to UISearchDisplayController during the search
searchBar.delegate = (id <UISearchBarDelegate>)self.searchDisplayController;
return YES;
}
#pragma mark <UISearchDisplayDelegate>
- (void) searchDisplayControllerDidBeginSearch:(UISearchDisplayController
*)controller {
// Un-hide the navigation bar that UISearchDisplayController hid
[self.navigationController setNavigationBarHidden:NO animated:NO];
}
- (void) searchDisplayControllerWillEndSearch:(UISearchDisplayController
*)controller {
UISearchBar *searchBar = (UISearchBar *)self.navigationItem.titleView;
// Manually resign search mode
[searchBar resignFirstResponder];
// Take back control of the search bar
searchBar.delegate = self;
}
答案 7 :(得分:3)
非常好的解决方案,但它在iOS6下崩溃我的应用程序。我必须进行以下修改才能使其正常工作。
@implementation ICSearchDisplayController
- (void)setActive:(BOOL)visible animated:(BOOL)animated
{
if (visible == YES) {
[super setActive:visible animated:animated];
[self.searchContentsController.navigationController setNavigationBarHidden:NO animated:NO];
} else {
[super setActive:NO animated:NO];
}
}
答案 8 :(得分:3)
这似乎为我解决了这个问题。在iOS5 / 6.1中都进行了测试。没有我能看到的视觉问题。
- (void)viewDidAppear
{
[super viewDidAppear];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillAppear:) name:UIKeyboardWillShowNotification object:nil];
}
-(void)viewWillDisappear:(BOOL)animated{
[super viewWillDisappear:animated];
[[NSNotificationCenter defaultCenter] removeObserver:self];
}
- (void)keyboardWillAppear:(NSNotification *)notification
{
[self.navigationController setNavigationBarHidden:NO animated:NO];
}
-(void)viewDidLayoutSubviews{
[self.navigationController setNavigationBarHidden:NO animated:NO];
}
答案 9 :(得分:3)
iOS 7搞砸了一些东西......对我来说这完美无缺:
/**
* Overwrite the `setActive:animated:` method to make sure the UINavigationBar
* does not get hidden and the SearchBar does not add space for the statusbar height.
*
* @param visible `YES` to display the search interface if it is not already displayed; NO to hide the search interface if it is currently displayed.
* @param animated `YES` to use animation for a change in visible state, otherwise NO.
*/
- (void)setActive:(BOOL)visible animated:(BOOL)animated
{
[[UIApplication sharedApplication] setStatusBarHidden:YES];
[self.searchContentsController.navigationController setNavigationBarHidden:YES animated:NO];
[super setActive:visible animated:animated];
[self.searchContentsController.navigationController setNavigationBarHidden:NO animated:NO];
[[UIApplication sharedApplication] setStatusBarHidden:NO];
}
显示/隐藏状态栏的原因
答案 10 :(得分:1)
我认为最好的解决方案是自己实现UISearchDisplayController。
这并不困难。您只需要为UIViewController实现UISearchBarDelegate并包含一个UITableView来显示您的搜索结果。
答案 11 :(得分:0)
@ Pavel的作品完美无缺。但是,我试图把它变成一个UIPopoverController,当搜索栏的文本字段成为第一个响应者时,字段中的文本被轻微推动,看起来有点难看,所以我通过调用super
来修复它方法用
animated
设置为NO
。
答案 12 :(得分:0)
正如jrc所指出的那样“解开UISearchDisplayController来控制任何UISearchBar”似乎对我有用。如果我在创建UISearchDisplayController时将nil作为参数传递,则导航栏始终保持可见:
searchDisplayController = [[UISearchDisplayController alloc] initWithSearchBar:nil contentsController:self];
答案 13 :(得分:0)
我在我的ViewController上添加了自定义导航栏,这个导航栏在搜索时被隐藏了,这是一个快速但不太好的修复
- (void)searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText{
[self.view addSubview:_navBar];
}
_navBar是以编程方式添加的UINavigationBar, 这样做有助于导航栏隐藏。
答案 14 :(得分:0)
只是想加入stigi的答案。当您取消搜索并再次开始搜索时 - 搜索结果表将不会对触摸作出反应,因此您需要添加下一行
self.searchResultsTableView.alpha = 1;
如此更新的代码看起来是下一个方式
- (void)setActive:(BOOL)visible animated:(BOOL)animated;
{
if(self.active == visible) return;
if (visible) {
[self.searchContentsController.navigationController setNavigationBarHidden:YES animated:NO];
[super setActive:visible animated:animated];
[self.searchContentsController.navigationController setNavigationBarHidden:NO animated:NO];
self.searchResultsTableView.alpha = 1;
[self.searchBar becomeFirstResponder];
} else {
[super setActive:visible animated:animated];
[self.searchBar resignFirstResponder];
}
}