我在嵌入导航控制器的控制器中呈现UISearchController
。将出现默认动画,其中搜索框从导航栏的顶部向下拉。
在我的情况下,这不是一个好的用户体验,因为当用户点击屏幕中间的UITextField
时,我会提供搜索。我想做的是让UITextField
浮动到顶部并变形到搜索框中,但我无法想象如何做到这一点。
这就是我所拥有的:
class PlacesSearchController: UISearchController, UISearchBarDelegate {
convenience init(delegate: PlacesAutocompleteViewControllerDelegate) {
let tableViewController = PlacesAutocompleteContainer(
delegate: delegate
)
self.init(searchResultsController: tableViewController)
self.searchResultsUpdater = tableViewController
self.hidesNavigationBarDuringPresentation = false
self.definesPresentationContext = true
self.searchBar.placeholder = searchBarPlaceholder
}
}
private extension ShowAddressViewController {
@objc func streetAddressTextFieldEditingDidBegin() {
present(placesSearchController, animated: true, completion: nil)
}
}
我希望文本字段能够飞到导航栏,而不是从顶部开始搜索。我所追求的是与iOS 11 File应用程序相同的效果:
屏幕中间有一个文本字段,然后在点击它时动画到导航栏。但在我的情况下,文本字段在屏幕中较低,而不是导航栏的原始部分。
答案 0 :(得分:14)
UISearchController是一个非常难以定制的组件。根据我的经验,我可以说,最好是按原样使用它而不需要任何激烈或重要的定制。否则,自定义可能会导致代码混乱,全局状态变量,UIView层次结构的运行时技巧等。 如果仍然需要特定的行为,最好从头开始实施搜索控制器或使用第三方搜索控制器。
看起来UISearchController设计用于与表标题视图中安装的UITableView和UISearchBar配合使用。即使是苹果官方代码示例和文档也提供了这样的使用示例(请参阅UISearchController)。尝试在其他地方安装UISearchBar经常会导致搜索栏框架,位置,抽搐动画,方向更改等等各种丑陋的副作用。
从iOS 11开始,UINavigationItem获得searchController属性。它允许将搜索控制器集成到您的导航界面中,因此搜索看起来与iOS文件或iOS AppStore应用程序完全相同。 UISearchController的行为仍然与另一个组件耦合,但我相信它总是比与UITableView耦合更好。
从我的角度来看,有几种可能的解决方案可以解决您的问题。我将按照增加的努力提供它们,这是实施所需的:
我希望这会有所帮助。
更新:
我已经实现了我在第3点描述的方法。以下是它的工作原理:
您可以找到代码段here。请注意,这只是代码示例,可能存在未处理的情况。然后检查两次。
答案 1 :(得分:3)
在ViewDidLoad中设置搜索控制器,如下所示:
func setupSearchController() {
self.searchController = UISearchController(searchResultsController: nil)
self.searchController.delegate = self
self.searchController.searchBar.delegate = self
definesPresentationContext = true
self.searchController.dimsBackgroundDuringPresentation = false
self.searchController.searchBar.sizeToFit()
searchView.addSubview(self.searchController.searchBar)
self.searchController.searchBar.isHidden = true
self.searchController.searchBar.tintColor = UIColor.white
self.searchController.searchBar.showsCancelButton = false
UITextField.appearance(whenContainedInInstancesOf: [UISearchBar.self]).tintColor = session?.makeColor(fromHexString: TYPE_COLOR, alpha: 1.0)
self.searchController.searchBar.isTranslucent = false
self.searchController.searchBar.barTintColor = UIColor(red: 239.0 / 255.0, green: 135.0 / 255.0, blue: 1.0 / 255.0, alpha: 1.0)
}
此方法将在searchview内以编程方式设置searchcontroller。
现在你只需要以编程方式显示searchcontroller。在步骤2中单击“按钮的方法”。在下面的方法名称中显示showsearchAnimation:
func ShowSeachAnimation() {
searchFrame = searchView.frame (add one global variable "searchFrame" in controller which saves searchView.frame so it will be used when cancel button clicked on search)
self.btnSearch.isHidden = true
var yAxis : CGFloat = 20
if #available(iOS 11 , *) {
yAxis = 8
} else {
yAxis = 20
}
searchView.translatesAutoresizingMaskIntoConstraints = true
searchView.frame = CGRect(x: 0, y: yAxis, width: view.frame.size.width, height: view.frame.size.height - yAxis)
self.searchController.searchBar.isHidden = false
self.searchController.searchBar.becomeFirstResponder()
self.searchController.searchBar.showsCancelButton = true
self.searchBar(self.searchController.searchBar, textDidChange: "")
searchView.layoutIfNeeded()
}
对于隐藏搜索栏,在searchcontroller委托中添加名为“searchbarcancelbuttonclicked”的搜索隐藏方法:
func searchViewHideAnimation() {
self.removeNavigationBar()
self.navigationController?.isNavigationBarHidden = false
self.searchController.searchBar.text = " "
self.searchController.searchBar.isHidden = true
UIView.animate(withDuration: 0.3, animations: {() -> Void in
self.searchView.frame = self.searchFrame!
self.btnSearch.isHidden = false
}, completion: {(_ finished: Bool) -> Void in
self.searchView.layoutIfNeeded()
})
}
答案 2 :(得分:2)
您可以尝试使用我的https://github.com/Blackjacx/SHSearchBar本质上是您的文字字段。您可以在左侧,右侧和顶部添加约束,并在文本字段编辑开始时调整顶部约束。同时,使用叠加视图隐藏导航栏动画并使背景变灰。通过这种方式,您可以最大限度地控制动画,这种方法并不像听起来那么困难。