hea*_*iti 12 objective-c uisearchbar ios swift uisearchcontroller
如何覆盖属于UISearchController的searchBar的默认动画?
好的,所以我正在尝试为附加到UISearchController的UISearchBar变为活动状态时创建自定义动画.似乎标准动画期望searchBar以占据屏幕的宽度开始.动画开始时缩小搜索栏并在其右侧的取消按钮中淡入淡出.
我希望我的searchBar以小的状态开始,大约是屏幕宽度的一半,以便允许两个按钮放在它旁边的导航栏中.
当searchBar变为活动状态时,我希望动画扩展searchBar并使取消按钮淡入.
当searchBar被解除时,我希望发生完全相反的动画:取消按钮淡出和searchBar缩小到它的原始大小.
我找到了一种方法,通过使用UISearchControllerDelegate方法presentSearchController来实现所需的呈现动画:
func presentSearchController(searchController: UISearchController) {
// Animate Buttons
UIView.animateWithDuration(0.1, animations: {
// First Hide Buttons
self.createMoxyButton.alpha = 0
self.centerMapButton.alpha = 0
})
// Animate Search Bar
UIView.animateWithDuration(0.5, animations: {
// Search Bar
searchController.searchBar.frame = CGRectMake(searchController.searchBar.frame.origin.x, searchController.searchBar.frame.origin.y, self.wBounds - 40, searchController.searchBar.frame.height)
self
})
}
Run Code Online (Sandbox Code Playgroud)
但我无法实现解雇动画.我已经尝试使用didDismissSearchController:和willDismissSearchController:委托方法但它导致奇怪的行为,并且不使用我在这些相应的委托方法中设置的帧的动画.当searchBar被解除时,它将扩展到全屏宽度,同时淡出取消按钮,然后它会立即将searchBar的帧更改回原始大小,忽略我的动画.我也尝试使用removeAllAnimation()方法尝试阻止默认动画发生,但无济于事.
func didDismissSearchController(searchController: UISearchController) {
searchController.searchBar.layer.removeAllAnimations()
// Animate
UIView.animateWithDuration(0.5, animations: {
// Show hidden buttons
self.createMoxyButton.alpha = 1
self.centerMapButton.alpha = 1
// Search Bar
searchController.searchBar.frame = CGRectMake(searchController.searchBar.frame.origin.x, searchController.searchBar.frame.origin.y, self.wBounds - 10 - self.createMoxyButton.frame.size.width - 20 - self.centerMapButton.frame.size.width - 20, searchController.searchBar.frame.height)
self
})
}
Run Code Online (Sandbox Code Playgroud)
Gif动画以处于活动状态的searchBar开始,并且可以看到取消按钮

我不能声称这会产生超级平滑的动画,但它看起来并不可怕,并且可能会有所帮助(甚至正是您所需要的)。如果您想尝试一下,可以创建一个新项目(单视图应用程序),然后添加导航控制器作为初始控制器,并将类对象添加ViewController为其根控制器(只是为了快速获取导航栏)。下面的代码是我的完整实现ViewController
import UIKit
class ViewController: UIViewController,UISearchBarDelegate,UISearchControllerDelegate,UISearchResultsUpdating {
lazy var createMoxyButton:UIBarButtonItem = {
//customize this as your equire
let button = UIBarButtonItem(title: "Done", style: .Plain, target: nil, action: nil)
return button
}()
lazy var centerMapButton:UIBarButtonItem = {
//customize this as your equire
let button = UIBarButtonItem(title: "Done", style: .Plain, target: nil, action: nil)
return button
}()
lazy var searchController:UISearchController = {
let controller = UISearchController(searchResultsController: self)
controller.delegate = self
controller.searchResultsUpdater = self
controller.dimsBackgroundDuringPresentation = false
controller.hidesNavigationBarDuringPresentation = false
return controller
}()
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
self.navigationItem.titleView = self.searchController.searchBar
self.navigationItem.rightBarButtonItems = [self.centerMapButton,self.createMoxyButton]
self.edgesForExtendedLayout = UIRectEdge.None
self.searchController.searchBar.delegate = self
}
func updateSearchResultsForSearchController(searchController: UISearchController) {
}
func searchBarTextDidBeginEditing(searchBar: UISearchBar) {
//this needs to be done because in shouldEndEditing
//we need to set it to false to smooth animation
searchBar.showsCancelButton = true
self.navigationItem.setRightBarButtonItems(nil, animated: true)
}
func searchBarShouldEndEditing(searchBar: UISearchBar) -> Bool {
searchBar.showsCancelButton = false
self.navigationItem.rightBarButtonItems = [self.centerMapButton,self.createMoxyButton]
return true
}
}
Run Code Online (Sandbox Code Playgroud)