简体   繁体   English

活动时 UISearchController 的 UISearchBar 移出屏幕

[英]UISearchBar of UISearchController moves off screen when active

I need to have a UISearchBar above a UITableView (ie. the search bar is not part of the table view), and what I found is that when the search bar is activated, it moves off screen.我需要在UITableView上方有一个UISearchBar (即搜索栏不是表格视图的一部分),我发现当搜索栏被激活时,它会移出屏幕。

I did a fair bit of search and could not find a solution, there are 'search bar off screen' issues but they are adding search bar to table's header view and tweaking properties like definesPresentationContext fixed it.我做了一些搜索,但找不到解决方案,存在“屏幕外搜索栏”问题,但他们正在将搜索栏添加到表格的标题视图并调整诸如definesPresentationContext属性definesPresentationContext修复它。

My view hierarchy:我的视图层次结构:

VC's view |— top view |— segmented control |— search bar |— table view VC的视图|-顶视图|-分段控件|-搜索栏|-表格视图

Looks like UISearchController expects the search bar to be inside the table view, and always shifts the table view so that the search bar moves to the very top of screen.看起来 UISearchController 期望搜索栏位于表格视图内,并且总是移动表格视图,以便搜索栏移动到屏幕的最顶部。

Anyone having the same issue and found a solution?有人遇到同样的问题并找到了解决方案吗?

Thanks a lot!非常感谢!

// Swift 5 // 斯威夫特 5

// if you are using UISearch Controller then simply add line below to your viewDidLoad() and it will fix the issue. // 如果您正在使用 UISearch 控制器,那么只需将下面的行添加到您的 viewDidLoad() 中,它将解决该问题。

override func viewDidLoad() {
     super.viewDidLoad()

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

I believe putting searchBar inside tableView is not mandatory.我相信将 searchBar 放在 tableView 中不是强制性的。 I had same issue some time back.前段时间我遇到了同样的问题。 All you need to do is setting proper auto layout constraint.您需要做的就是设置适当的自动布局约束。 Adjust leading and trailing of searchView as align to leading and trailing of the tableView.调整 searchView 的前导和尾随与 tableView 的前导和尾随对齐。 Also release the margin property from constraints.同时从约束中释放边距属性。 Hope this may help you.希望这可以帮助你。

After a few tries, I've found the reason being that when the UISearchBar is activated, UISearchController removes it from your view and puts it on its own view with a table view for showing the results, since I use auto-layout for the search bar, by removing it, some of the constraints are screwed up.经过几次尝试,我发现原因是当UISearchBar被激活时, UISearchController会将它从您的视图中删除,并将其放在自己的视图中,并使用表视图来显示结果,因为我使用自动布局进行搜索酒吧,通过删除它,一些约束被搞砸了。 So my solution was to not use auto layout for the UISearchBar from UISearchController .所以我的解决方案是不使用UISearchBarUISearchController自动布局。

Updates更新

After further testing I decided to just implement the UISearchBar delegate and stop using the UISearchController since I was just reusing my UICollectionView for the results.经过进一步测试,我决定只实现 UISearchBar 委托并停止使用 UISearchController,因为我只是将 UICollectionView 重用于结果。 Found a great guide on how three different methods to implement the SearchBar.找到了一个关于如何实现 SearchBar 的三种不同方法很好的指南

Edge Case #1边缘案例#1

TLDR TLDR

Enable clips to bounds on the containing view.启用剪辑到包含视图的边界。 Or if you have a collection view cell that has a user-generated content view, enable clips to bounds on that content view.或者,如果您有一个包含用户生成的内容视图的集合视图单元格,请启用剪辑到该内容视图的边界。

Details:详情:

An additional very important fact is that you may have the search bar embedded in a container view.另一个非常重要的事实是,您可能将搜索栏嵌入到容器视图中。 This can cause issues if the container view does not have clips to bounds enabled.如果容器视图没有启用剪辑到边界,这可能会导致问题。 Other examples of this being a problem is the user-generated content views in UICollectionViewCells.这个问题的其他例子是 UICollectionViewCells 中用户生成的内容视图。 Compare the setting on a UITableViewCell auto-generated content view to observe the difference.比较 UITableViewCell 自动生成的内容视图上的设置以观察差异。

Summary总结

A Boolean value that determines whether subviews are confined to the bounds of the view.一个布尔值,用于确定子视图是否被限制在视图的边界内。 Declaration声明

var clipsToBounds: Bool { get set } Discussion var clipsToBounds: Bool { get set } 讨论

Setting this value to true causes subviews to be clipped to the bounds of the receiver.将此值设置为 true 会导致子视图被裁剪到接收器的边界 If set to false, subviews whose frames extend beyond the visible bounds of the receiver are not clipped.如果设置为 false,则不会裁剪帧超出接收器可见边界的子视图。 The default value is false.默认值为假。

Swift 4.x Solution Swift 4.x 解决方案

In my case, this was happening both inside a UICollectionView and inside of a UIStackView.就我而言,这发生在 UICollectionView 和 UIStackView 内部。 I was able to keep my searchBar in place after noticing the following info in the searchBar quick help.在注意到搜索栏快速帮助中的以下信息后,我能够将搜索栏保持在原位。

Summary总结

The search bar to install in your interface.要在您的界面中安装的搜索栏。 Declaration声明

var searchBar: UISearchBar { get } Discussion var searchBar: UISearchBar { get } 讨论

Before presenting your searchable content, install the search bar in this property somewhere into your view controller's interface .在呈现可搜索内容之前将此属性中的搜索栏安装到视图控制器界面中的某个位置 The search bar becomes the starting point for searching your contents.搜索栏成为搜索内容的起点。 Interactions with the search bar are handled automatically by the UISearchController object, which notifies the object in the searchResultsUpdater property whenever the search information changes.与搜索栏的交互由 UISearchController 对象自动处理,只要搜索信息发生变化,它就会通知 searchResultsUpdater 属性中的对象。 To use a custom subclass of UISearchBar, subclass UISearchController and implement this property to return your custom search bar.要使用 UISearchBar 的自定义子类,子类 UISearchController 并实现此属性以返回您的自定义搜索栏。

After that I was able to resolve the issue successfully by doing the following:之后,我能够通过执行以下操作成功解决问题:

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

Sometime later I assign the searchBar from the searchController to the searchBar in my UIViewController...一段时间后,我将 searchBar 从 searchController 分配给 UIViewController 中的 searchBar ...

BTW - I embed my searchBar in a container UIView that has all the contraints I need to keep it in place.顺便说一句 - 我将我的 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
}

If you choose to use UISearchBar without an UISearchController, which I have found much easier for keeping UISearchBar within its initial bounds, here is the code template:如果您选择在没有 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()
    }
    
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM