NavigationBar中的iOS 11 SearchBar

时间:2017-07-27 11:52:35

标签: uinavigationbar uisearchbar ios11

借助iOS 11,Apple重新设计了UISearchBar,使角落更圆,高度更大。只需使用navigationItem.titleView = searchBar将其设置为navigationItem的titleView,就可以将UISearchBar添加到navigationBar。

然而,在iOS 11中它似乎不再像预期的那样工作。 看看我们使用iOS 10和iOS 11比较相同设置的屏幕

iOS 10 enter image description here

iOS 11 enter image description here

您可以清楚地看到SearchBar增加了NavigationBar的大小,但条形按钮没有正确对齐。此外,searchBar不再使用左侧的可用空间。

将searchBar放入包装视图以获取iPad上的取消按钮,如Cancel button is not shown in UISearchBar所述,似乎不再有效,因为搜索栏根本不可见。

如果有人有类似问题或者已经知道如何修复/改进这一点,我将非常感激。

这是使用Xcode 9 Beta 4构建的。也许将来的版本可以解决这个问题。

更新

由于这没有得到解决,我们决定使用以下解决方案。 我们向NavBar添加了一个新的UIBarButtonItem,然后它呈现了一个新的ViewController,我们只将一个searchBar放入NavBar,而这似乎没有用。使用所选答案可能是最佳解决方案,因为Apple 11和iOS 11希望我们使用这种新设计,即使它没有给我们原先想要的结果。另一种可能解决此问题的方法可能是自定义SearchBar,但这是另一个主题。

8 个答案:

答案 0 :(得分:49)

iOS 11中的navigationItem上有一个新的searchController属性。

https://developer.apple.com/documentation/uikit/uinavigationitem/2897305-searchcontroller

像这样使用......

if #available(iOS 11.0, *) {
     navigationItem.searchController = searchController
} else {
     // Fallback on earlier versions
     navigationItem.titleView = searchController?.searchBar
}

在Objective-C中,if语句如下所示:

if (@available(iOS 11.0, *)) {

在iOS 11上,如果您未设置navigationItem.hidesSearchBarWhenScrolling = false,搜索栏最初可能会被隐藏,除非用户向下滚动以显示它。如果您将其设置为false,则会显示堆叠在标题所在的下方,而无需用户滚动。

答案 1 :(得分:16)

您可以通过添加高度为44的约束来更改iOS 11中UISearchBar的高度:

{{1}}

答案 2 :(得分:4)

我遇到了同样的问题,经过几天搜索问题后,我找到了这个页面 - https://translate.google.com/translate?hl=en&sl=zh-CN&u=http://www.jianshu.com/p/262f6e34a7d3&prev=search

这个页面引出了这个git repo - https://github.com/DreamTravelingLight/searchBarDemo - 这个演示项目展示了如何使用titleView的旧方法仍然有一个没有大小问题的searchBar。

关键是这些

_searchBar = [self addSearchBarWithFrame:CGRectMake(0, 0, kScreenWidth - 2 * 44 - 2 * 15, 44)];
UIView *wrapView = [[UIView alloc] initWithFrame:_searchBar.frame];
[wrapView addSubview:_searchBar];
self.navigationItem.titleView = wrapView;

如果您将UISearchBar嵌入到视图中,并将该wrapView设置为titleView,则UISearchBar将具有您为其设置的大小,并且将按预期适合导航栏。

谢谢, 大卫

答案 3 :(得分:1)

我认为您必须处理将新的UINavigationItem.searchController属性设置为UISearchController对象。这就是你如何获得消息中所见的新效果。看起来旧的行为已经彻底消失了。我希望我错了,但整个API都进行了大修11.我知道它一般都是错误的所以我们会看到更新的测试版和GM如果这个问题得到解决。 (在Beta 6时写作)

答案 4 :(得分:1)

这对我有所帮助:

    if ([self.navigationItem respondsToSelector:@selector(setSearchController:)])
    {
        [self.navigationItem performSelector:@selector(setSearchController:) withObject:self.searchController];
    }
    else
    {
        self.tableView.tableHeaderView = self.searchController.searchBar;
    }

答案 5 :(得分:1)

如果您确实要在iOS 11+ UISearchBar中使用本机navigationBar (并避免创建自定义组件的需要),则可以创建一个容器查看该searchBar以完全控制框架。该容器视图将是您传入的searchBar的超级视图。

类似的东西:

class SearchBarContainerView: UIView {

    let searchBar: UISearchBar

    required init?(coder aDecoder: NSCoder) {
        searchBar = UISearchBar()
        super.init(coder: aDecoder)
    }

    init(searchBar: UISearchBar) {
        self.searchBar = searchBar
        super.init(frame: CGRect(x: 0.0, y: 0.0, width: 0.0, height: 44.0))
        addSubview(searchBar)
    }

    override func layoutSubviews() {
        super.layoutSubviews()
        searchBar.frame = bounds
    }
}

然后:

let containerView = SearchBarContainerView(searchBar: searchController.searchBar)
containerView.frame.size.width = navigationController?.navigationBar.frame.size.width ?? 0.0
navigationItem.titleView = containerView
  

请注意,这只是一个快速演示,尚不能用于navigationBar帧更改(显示旋转等)。你可以用例如解决autoresizingMask

答案 6 :(得分:0)

我尝试了searchControllersearchBar,但发现searchBar符合我的要求(单击搜索按钮进行搜索)。

-(void)searchBarSetUp{
//Search button to reload the radio content.
self.searchButton.action = @selector(addSearchBarToNavigationTitleView);
self.searchButton.target = self;

//search bar initialization
searchBar = [[UISearchBar alloc] initWithFrame:CGRectZero];
searchBar.delegate = self;
searchBar.showsCancelButton = YES;
[searchBar sizeToFit]; }

-(void)addSearchBarToNavigationTitleView {
// Install the search bar as the table header.
self.navigationItem.titleView = searchBar;}

如果我使用searchControl,我也将面临处理黑屏的困难。

答案 7 :(得分:0)

在iOS 14以上版本中进行汇总

首先修复推动会导致额外的高度:

override func viewWillDisappear(_ animated: Bool) {
    super.viewWillDisappear(animated)
    navigationController?.view.setNeedsLayout() // force update layout
    navigationController?.view.layoutIfNeeded() // to fix height of the navigation bar
}

其次将pop固定到原点高度:

extendedLayoutIncludesOpaqueBars = true

以上所有代码均在带有搜索栏的控制器中设置。