在WWDC 2014演讲中#34;内部展示控制器"演示者展示了如何在UITableView中设置UISearchController。他们通过设置searchController的searchBar框架,然后将其设置为tableView的tableHeaderView来完成此操作。不幸的是,对于UICollectionView,没有相当于tableHeaderView的东西。使用UISearchDisplayController,这很简单:创建一个UISearchBar并将其添加到自定义UICollectionView节头,然后使用搜索栏初始化UISearchDisplayController。问题是,您无法使用UISearchBar初始化UISearchController,甚至设置searchBar,因为它是一个只读属性。我想我真正的问题是,我的选择是什么?有没有好的"没有UISearchDisplayController或UISearchController实现搜索的方法?
答案 0 :(得分:14)
使用UISearchDisplayController,这很简单:创建一个UISearchBar并将其添加到自定义UICollectionView节头,然后使用搜索栏初始化UISearchDisplayController
为您创建UISearchController中的搜索栏。当您在数据源方法中询问补充视图时
- (UICollectionReusableView *)collectionView:(UICollectionView *)collectionView viewForSupplementaryElementOfKind:(NSString *)kind atIndexPath:(NSIndexPath *)indexPath
将searchController.searchBar添加为补充视图的子视图。别忘了打电话
[searchController.searchBar sizeToFit]
为搜索栏指定合适的大小。
答案 1 :(得分:4)
我的第一个问题:为什么你不能翻转逻辑而不是创建搜索栏,首先创建一个UISearchController,抓住它的搜索栏并将其添加到部分标题中?
其次,集合视图布局不像表视图那么简单。搜索使用集合视图布局来猜测您的意图很困难,而表格视图非常简单。因此,在集合视图的情况下,您可以自由地向视图添加搜索栏,但将其设置为活动状态将需要一些工作。 (子类UISearchController并返回你自己的动画控制器,然后做你想要的任何动画。或者只是在子类上实现UIViewControllerAnimatedTransitioning中的方法而不要调用super,两者都应该工作)
您可能想要尝试的是让屏幕外显示搜索栏。这是一个内置动画,UISearchController在调用setActive:时支持,搜索栏不在视图层次结构中的任何位置。日历就是这样......它非常酷。您可以将搜索缩小为驱动演示文稿的图标,而不是始终存在巨大的搜索栏。
最后,肯定会有错误。 请提交错误,如果您无法按照自己的想法开展工作。我知道,这是一个破纪录,但它确实是必要的。
答案 2 :(得分:0)
这里接受的答案似乎已经过时,在回答时没有牢记几件事。如下:
UISearchController.searchbar
视图作为补充视图返回,但您不能这样做,因为类型不匹配。UISearchController.searchbar
添加为子视图,但是请耐心等待,您必须从其他补充视图中删除该视图,因为该补充视图可能会重新在其他部分中使用(通常在collectionView中使用多个部分)最近,我正在努力实现这种用户体验,以在具有多个部分的collectionView上进行搜索。这是我的解决方法。
在情节提要中,使用UIViewController
而不是UICollectionViewController
。在ViewController中,我像下面这样添加一个UIView
和一个UICollectionView
---------ViewController---------- | | | UIView | | | |===============================| | | | | | | | | | | | UICollectionView | | | | | | | | | | | | | ---------------------------------
顶部UIView
具有高度限制,并固定到top
,left
和right
。底部CollectionView
固定到bottom
,left
和right
,并且顶部视图和底部集合视图之间的垂直距离设置为零。顶视图的子类为FillSubView
,如下所示
FillSubView.swift
import UIKit
class FillSubView: UIView {
override func didAddSubview(_ subview: UIView) {
subview.frame = self.bounds
}
override func layoutSubviews() {
super.layoutSubviews()
subviews.first?.frame = self.bounds
}
}
它的作用是,每次添加子视图或FillSubView
的布局发生变化时,第一个子视图都会调整为该内容的大小。您可能会发现为什么我不使用约束来固定子视图。我的意图是将UISearchController.searchbar添加为FillSubView中的子视图。当UISearchController激活和停用后,此搜索栏将被删除并重新添加到上一个父视图中。在这种情况下,如果您严格要将搜索栏固定到FillSubView,则可以覆盖
- (void)didAddSubview:(UIView *)subview;
将子视图(搜索栏)固定到父视图(顶,底,左,右)。从超级视图中删除时,约束将被自动删除。
现在说视图控制器被子类化为MyViewController
。我采用了IBOutlet
,其中包括顶部UIView,CollectionView和顶部视图高度约束,如下所示:
@IBOutlet weak var searchBarContainer: UIView! // top view
@IBOutlet weak var collectionView: UICollectionView! // bottom collection view
@IBOutlet weak var searchContainerHeightConstraint: NSLayoutConstraint! // top view height constraint
然后在MyViewController
中,我添加了一个函数来如下设置searchController
private func setupSearchController() {
searchController = UISearchController.init(searchResultsController: nil)
searchController?.searchResultsUpdater = self
searchController?.dimsBackgroundDuringPresentation = false
searchController?.searchBar.placeholder = "Search"
if let searchbar = searchController?.searchBar {
searchBarContainer.addSubview(searchbar)
searchContainerHeightConstraint.constant = searchbar.bounds.height
}
definesPresentationContext = true
}
我从ViewDidLoad
的ViewController重载方法中调用此方法。这里的重点是FillSubView
类,它沿整个视图填充了搜索栏。
委托searchResultUpdater
的实现非常普遍,只是过滤掉用户在搜索栏中键入任何文本时要显示的内容。
这样,我实现了自己的目标,并且也符合前面所述的3个问题。
希望有帮助。