Iphone 防止UISearchDisplayController隐藏导航栏

Iphone 防止UISearchDisplayController隐藏导航栏,iphone,iphone-sdk-3.0,uinavigationcontroller,uisearchdisplaycontroller,Iphone,Iphone Sdk 3.0,Uinavigationcontroller,Uisearchdisplaycontroller,每当用户开始编辑UISearchDisplayController的搜索栏时,搜索控制器将变为活动状态,并在显示搜索表视图时隐藏视图的导航栏。有没有可能在不重新实现的情况下阻止UISearchDisplayController隐藏导航栏?我刚刚对UISearchDisplayController进行了一些调试,发现它正在调用UINavigationController上的私有方法来隐藏导航栏。这发生在-setActive:animated:。如果您将UISearchDisplayControll

每当用户开始编辑
UISearchDisplayController
的搜索栏时,搜索控制器将变为活动状态,并在显示搜索表视图时隐藏视图的导航栏。有没有可能在不重新实现的情况下阻止
UISearchDisplayController
隐藏导航栏?

我刚刚对UISearchDisplayController进行了一些调试,发现它正在调用UINavigationController上的私有方法来隐藏导航栏。这发生在-setActive:animated:。如果您将UISearchDisplayController子类化并用以下代码覆盖此方法,则可以通过假装导航栏已隐藏来防止其隐藏

- (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上测试。

尝试了另一种方法,没有对UISearchDisplayController进行子类化。在为UISearchDisplayController设置委托的UIViewController类中,实现searchDisplayControllerDidBeginSearch:并添加use

[self.navigationController setNavigationBarHidden:NO animated:YES];

帮了我一把,希望对我有帮助。

以上的答案对我不太合适。我的解决方案是愚弄UISearchDisplayController,使其认为没有UINavigationController

在视图控制器中,添加此方法

- (UINavigationController *)navigationController {
    return nil;
}

这对我来说没有不良副作用,尽管这看起来是个非常糟糕的主意。。。如果需要使用导航控制器,请使用
[super-navigationController]

我认为最好的解决方案是自己实现UISearchDisplayController


没那么难。您只需要为UIViewController实现UISearchBarDelegate,并包含一个UITableView来显示搜索结果。

我在解决一个稍微不同的问题时遇到了这个问题。在使用UISearchDisplayController时,我希望搜索栏位于导航栏中(而不是下方)

将搜索栏放在导航栏中并不难(请参阅)。但是,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标记
-(BOOL)搜索栏应开始编辑:(UISearchBar*)搜索栏{
//手动激活搜索模式
//使用animated=NO,这样我们就可以立即再次取消隐藏它
[self.searchDisplayController设置活动:是动画:否];
//在搜索过程中将控制权移交给UISearchDisplayController
searchBar.delegate=(id)self.searchDisplayController;
返回YES;
}
#布拉格标记
-(void)SearchDisplayControllerdBeginSearch:(UISearchDisplayController)
*)控制器{
//取消隐藏UISearchDisplayController隐藏的导航栏
[self.navigationController setNavigationBarHidden:无动画:无];
}
-(无效)searchDisplayControllerWillEndSearch:(UISearchDisplayController)
*)控制器{
UISearchBar*搜索栏=(UISearchBar*)self.navigationItem.titleView;
//手动退出搜索模式
[搜索栏辞职FirstResponder];
//收回对搜索栏的控制权
searchBar.delegate=self;
}

最简单的解决方案,没有黑客攻击

@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

@帕维尔的工作非常好。然而,我试图将其放入UIPopoverController中,当搜索栏的文本字段成为第一响应者时,字段中的文本会被轻轻推送,这看起来有点难看,因此我通过调用
super
方法修复了它
animated
设置为
NO

这是一个非常好的解决方案,但它在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];
        }
    }

这似乎为我解决了问题。在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];
}
正如jrc指出的,“从控制任何UISearchBar的UISearchDisplayController上取下钩”似乎对我有效。如果在创建UISearchDisplayController时将nil作为参数传递,则导航栏始终可见:

searchDisplayController = [[UISearchDisplayController alloc] initWithSearchBar:nil contentsController:self];

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];
}

显示/隐藏状态栏的原因iOS 8引入的新的
UISearchController
类有一个属性
hidesNavigationBarDuringPresentation
,如果您想让导航栏保持可见,可以将该属性设置为false(默认情况下,它仍然是隐藏的).

我在我的ViewController上添加了自定义导航栏,它在搜索时被隐藏了,这是一个快速但不太好的修复方法

- (void)searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText{
    [self.view addSubview:_navBar];
}
_导航栏是通过编程方式添加的UINavigationBar,
这样做帮助我避免了导航栏的隐藏。

只是想添加到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];
    }
}

自iOS 8.0以来,通过将
UISearchController
self.searchController.hidesNavigationBarDuringPresentation
属性设置为false,可以实现相同的行为

Swift中的代码如下所示:

searchController.hidesNavigationBarDuringPresentation = false

这比公认的答案简单得多。当用户关注文本字段时,导航栏会再次上下滑动。使用动画:不,它会弹回到原来的位置。两种选择看起来都不好,有什么解决办法吗
searchController.hidesNavigationBarDuringPresentation = false