我在tvOS中创建了一个SearchController,该视图在水平滚动的CollectionView中显示了结果。
最终结果看起来非常可怕,因为当焦点从键盘移到结果时,键盘会自动关闭。
由于没有键盘时集合视图的高度较大,因此其上的元素会在集合视图中自动重新对齐。这使UX非常混乱。
您可以在以下GIF中看到问题。将焦点从键盘上移到结果上,甚至聚焦到非预期的元素上。 (用“七个”代替“五个”)
有什么方法可以避免键盘崩溃?我注意到,当结果视图包含不可滚动的视图时,键盘不会折叠,但是我需要使结果可滚动。
在这里您可以找到重现该问题的代码。
import UIKit
private var items = ["One", "Two", "Three", "Four", "Five", "Six", "Seven", "Eight", "Nine", "Ten", "Eleven", "Twelve"]
final class MySearchViewController: UIViewController, UICollectionViewDataSource {
override func viewDidLoad() {
super.viewDidLoad()
setUpView()
}
// MARK: - Private
private lazy var searchContainerViewController: UISearchContainerViewController = {
return UISearchContainerViewController(searchController: searchController)
}()
private lazy var searchController: UISearchController = {
let searchController = UISearchController(searchResultsController: searchResultsController)
return searchController
}()
private lazy var searchResultsController: UIViewController = {
let layout = UICollectionViewFlowLayout()
layout.scrollDirection = .horizontal
let searchResultsController = UICollectionViewController(collectionViewLayout: layout)
searchResultsController.collectionView.dataSource = self
MyCell.register(in: searchResultsController.collectionView)
return searchResultsController
}()
private func setUpView() {
embed(viewController: searchContainerViewController, inContainerView: view)
}
// MARK: - UICollectionViewDataSource
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return items.count
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: MyCell.reuseIdentifier, for: indexPath) as! MyCell
cell.titleLabel.text = items[indexPath.row]
return cell
}
}
class MyCell: UICollectionViewCell {
static var reuseIdentifier: String { return String(describing: self) + "ReuseIdentifier" }
var titleLabel: UILabel!
public static func register(in collectionView: UICollectionView) {
collectionView.register(MyCell.self, forCellWithReuseIdentifier: MyCell.reuseIdentifier)
}
override init(frame: CGRect) {
super.init(frame: frame)
titleLabel = UILabel(frame: bounds)
backgroundColor = .blue
contentView.addSubview(titleLabel)
}
override func didUpdateFocus(in context: UIFocusUpdateContext, with coordinator: UIFocusAnimationCoordinator) {
backgroundColor = isFocused ? .red : .blue
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
}
}
一种避免聚焦错误元素的解决方法是将固定高度分配给CollectionView。但是这样做仍然会隐藏键盘,从而在屏幕上留下很多多余的空白空间。
因为在这种情况下隐藏键盘是没有用的。我想让它始终可见。
这是对集合视图使用固定高度的结果。
答案 0 :(得分:3)
直到tvOS 14,苹果发布了新财产searchControllerObservedScrollView
:https://developer.apple.com/documentation/uikit/uisearchcontroller/3584820-searchcontrollerobservedscrollvi
通过在此属性上设置collectionView,SearchController会自动使搜索栏+键盘位置适应您的CollectionView偏移量。
您可以通过以下方式修改代码:
private lazy var searchController: UISearchController = {
let searchController = UISearchController(searchResultsController: searchResultsController)
if #available(tvOS 14.0, *) {
searchController.searchControllerObservedScrollView = (searchResultsController as? UICollectionViewController)?.collectionView
}
return searchController
}()
要摆脱可为空的类型转换,只需将searchResultsController
的返回类型更改为UICollectionViewController
。它不会影响您的实施。