正如标题所示,我将说明重现我的情况所需的最低限度。
我的导航控制器中嵌入了我的FakeViewController。它包含:
hidesNavigationBarDuringPresentation = true
分配给navigationItem的搜索控制器。单元格必须占据整个collectionView边界(如pageViewController),它会显示一个简单的viewController.view(图中浅蓝色)。
在viewDidLoad,一切都很好。当我点击searchBar时,导航栏消失,顶视图和collectionView向上移动。
但是当我点击取消按钮时,单元格仍然位于隐藏其内容部分的顶视图下方。
控制台打印:
The relevant UICollectionViewFlowLayout instance is <UICollectionViewFlowLayout: 0x7fefc6463b10>, and it is attached to <UICollectionView: 0x7fefc78a2000; frame = (0 180; 375 438); clipsToBounds = YES; autoresize = RM+BM; gestureRecognizers = <NSArray: 0x604000a48fd0>; layer = <CALayer: 0x60400022df20>; contentOffset: {0, 0}; contentSize: {375, 484}; adjustedContentInset: {0, 0, 0, 0}> collection view layout: <UICollectionViewFlowLayout: 0x7fefc6463b10>.
Make a symbolic breakpoint at UICollectionViewFlowLayoutBreakForInvalidSizes to catch this in the debugger.
查看调试视图Hierarchy,我发现collectionView具有正确的框架,而其单元格没有更新它。
我不知道如何强制单元格缩短:尝试使用自定义UICollectionViewFlowLayout或在取消轻敲后调用invalidateLayout()
,但问题仍然存在。
这是我的FakeViewControlelr实现:
class FakeViewController: UIViewController, UICollectionViewDelegateFlowLayout, UICollectionViewDelegate, UICollectionViewDataSource, UISearchBarDelegate {
//MARK: - Model
private var views = [UIView]()
//MARK: Outlets
@IBOutlet weak var collectionView: UICollectionView!
private var searchController = UISearchController(searchResultsController: nil)
override func viewDidLoad() {
super.viewDidLoad()
setupSearchController()
setupCollectionView()
}
//MARK: - Helpers
private func setupSearchController() {
searchController.obscuresBackgroundDuringPresentation = false
definesPresentationContext = true
searchController.searchBar.placeholder = "Search here"
searchController.searchBar.delegate = self
searchController.searchBar.searchBarStyle = .minimal
searchController.hidesNavigationBarDuringPresentation = true
navigationItem.searchController = searchController
navigationItem.hidesSearchBarWhenScrolling = false
}
private func setupCollectionView() {
guard let supersetListVC = self.storyboard?.instantiateViewController(withIdentifier: "SupersetListVC") else {return}
self.addChildViewController(supersetListVC)
self.views.append(supersetListVC.view)
self.collectionView.delegate = self
self.collectionView.dataSource = self
searchController.searchBar.delegate = self
self.collectionView.reloadData()
}
//MARK: - UICollectionViewDataSource
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return views.count
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cell", for: indexPath)
let displayedView = self.views[indexPath.row]
cell.contentView.addSubview(displayedView)
displayedView.frame = cell.contentView.bounds
return cell
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
//NOTICE: this method isn't called when navigationBar turns visible.
//Thats why I implemented searchBarCancellButtonClicked(_:)
return CGSize(width: collectionView.bounds.width, height: collectionView.bounds.height)
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetForSectionAt section: Int) -> UIEdgeInsets {
return UIEdgeInsets(top: 0, left: 0, bottom: 0, right: 0)
}
func searchBarCancelButtonClicked(_ searchBar: UISearchBar) {
self.collectionView.collectionViewLayout.invalidateLayout()
}
}
提前感谢您的帮助! 亲切的问候 的Alessandro