UISearchController 的 UISearchBar 在活动时移出屏幕

Posted

技术标签:

【中文标题】UISearchController 的 UISearchBar 在活动时移出屏幕【英文标题】:UISearchBar of UISearchController moves off screen when active 【发布时间】:2016-09-21 05:41:13 【问题描述】:

我需要有一个UISearchBar above 一个UITableView(即搜索栏不是表格视图的一部分),我发现当搜索栏被激活时,它移出屏幕。

我进行了相当多的搜索,但找不到解决方案,存在“屏幕外搜索栏”问题,但他们正在将搜索栏添加到表格的标题视图并调整属性,如 definesPresentationContext 已修复。

我的视图层次结构:

VC 的观点 |— 顶视图 |— 分段控制 |— 搜索栏 |— 表格视图

看起来 UISearchController 期望搜索栏位于表格视图内,并且总是移动表格视图以便搜索栏移动到屏幕的最顶部。

任何人有同样的问题并找到了解决方案?

非常感谢!

【问题讨论】:

【参考方案1】:

// 斯威夫特 5

// 如果您使用的是 UISearch 控制器,那么只需将下面的行添加到您的 viewDidLoad() 它将解决问题。

override func viewDidLoad() 
     super.viewDidLoad()

     // fixes the search moving to next screen when its active
     self.definesPresentationContext = true

【讨论】:

【参考方案2】:

更新

经过进一步的测试,我决定只实现 UISearchBar 委托并停止使用 UISearchController,因为我只是重用我的 UICollectionView 来获取结果。找到一个great guide on how three different methods 来实现SearchBar。

边缘案例 #1

TLDR

启用剪辑到包含视图的边界。或者,如果您有一个包含用户生成内容视图的集合视图单元格,请启用剪辑以限制该内容视图。

详情:

另外一个非常重要的事实是,您可以将搜索栏嵌入到容器视图中。如果容器视图没有启用剪辑到边界,这可能会导致问题。这个问题的其他例子是 UICollectionViewCells 中用户生成的内容视图。比较 UITableViewCell 自动生成的内容视图上的设置以观察差异。

总结

一个布尔值,用于确定子视图是否被限制在 视图的边界。声明

var clipsToBounds: Bool get set 讨论

将此值设置为 true 会导致 子视图被剪裁到边界 的接收器。如果设置为 false,则其框架超出的子视图 接收器的可见边界不会被剪裁。默认值 是假的。

Swift 4.x 解决方案

在我的例子中,这发生在 UICollectionView 和 UIStackView 内部。在 searchBar 快速帮助中注意到以下信息后,我能够将我的 searchBar 保持在原位。

总结

要安装在界面中的搜索栏。声明

var searchBar: UISearchBar get Discussion

在展示您的可搜索内容之前,中安装搜索栏 此属性位于视图控制器界面的某个位置。这 搜索栏成为搜索内容的起点。 与搜索栏的交互由 UISearchController 对象,它通知对象在 搜索信息更改时的 searchResultsUpdater 属性。 要使用 UISearchBar 的自定义子类,子类 UISearchController 并实现此属性以返回您的自定义搜索栏。

之后,我通过执行以下操作成功解决了问题:

let searchController = UISearchController(searchResultsController: nil)
var searchBar:UISearchBar!

稍后我将 searchBar 从 searchController 分配给我的 UIViewController 中的 searchBar...

顺便说一句 - 我将我的 searchBar 嵌入到一个容器 UIView 中,该容器具有保持它到位所需的所有约束。

func setupSearchController<T:UIViewController>(delegate vc:T) where T: UISearchResultsUpdating, T:UISearchBarDelegate 
    searchBar = searchController.searchBar //this is the key
    searchController.searchResultsUpdater = vc
    searchController.obscuresBackgroundDuringPresentation = false
    searchController.searchBar.placeholder = "Search".localized()
    searchController.dimsBackgroundDuringPresentation = false
    searchController.searchBar.delegate = vc
    searchController.searchBar.showsCancelButton = true
    definesPresentationContext = true
    self.searchMenu.addSubview(searchBar) 
    //searchMenu is a constrained UIView in my hierarchy

【讨论】:

【参考方案3】:

我相信将 searchBar 放入 tableView 不是强制性的。前段时间我有同样的问题。您需要做的就是设置适当的自动布局约束。将 searchView 的前导和尾随调整为与 tableView 的前导和尾随对齐。还要从约束中释放边距属性。希望这对您有所帮助。

【讨论】:

感谢您的回答,是的,如果我自己使用UISearchBar,完全没有问题,但是如果我使用新UISearchController 的搜索栏,它会显示一些奇怪的动画和错误- 搜索栏激活时的位置。找到另一篇帖子***.com/questions/31611874/…,PO提到“看起来UISearchController的设计者只考虑了searchBar在表头中的情况。”【参考方案4】:

经过几次尝试,我发现原因是当UISearchBar 被激活时,UISearchController 将其从您的视图中删除,并将其放在自己的视图中,并使用表格视图显示结果,因为我对搜索栏使用自动布局,通过删除它,一些约束被搞砸了。所以我的解决方案是不要对来自UISearchControllerUISearchBar 使用自动布局。

【讨论】:

你做了什么来放置搜索栏?【参考方案5】:

如果您选择在没有 UISearchController 的情况下使用 UISearchBar,我发现这样可以更容易地将 UISearchBar 保持在其初始范围内,这里是代码模板:

final class MyUIViewController: UIViewController 
    // MARK: Properties
    private let tableView = UITableView()
    private let searchBar = UISearchBar()
    ...

    // MARK: View Lifecycle
    override func viewDidLoad() 
        super.viewDidLoad()

        ...

        searchBar.delegate = self
        searchBar.sizeToFit()
        
        tableView.tableHeaderView = searchBar
    


extension MyUIVewController: UISearchBarDelegate 

    func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) 
        ... // Your code filtering tableView dataSource goes here

        tableView.reloadData()
    
    

【讨论】:

以上是关于UISearchController 的 UISearchBar 在活动时移出屏幕的主要内容,如果未能解决你的问题,请参考以下文章

UISearchController 结果 TableViewController 在 UISearchBar 为空时不清除结果

iOS UISearchController:等到 UISearchController 在取消搜索后被解除

UISearchController

UISearchController 与单元格布局混淆

UISearchController 没有响应

UISearchController 未显示