如何覆盖属于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 = …Run Code Online (Sandbox Code Playgroud) 我已经实现了UISearchController,它工作得很好,除了......
当我单击搜索栏时,导航栏会按预期消失.当我将手机旋转到横向视图时,我得到了这个有意义的视图.

但是,当我将手机旋转回纵向视图(仍然在搜索类型区域中选择)时,我得到以下视图.

您可以看到导航栏永远不会再出现.我觉得我正在实现一个基本的搜索控制器.什么可能导致这个?
self.venueSearchController = [[UISearchController alloc] initWithSearchResultsController:nil];
self.venueSearchController.searchResultsUpdater = self;
self.venueSearchController.searchBar.delegate = self;
self.venueSearchController.dimsBackgroundDuringPresentation = NO;
self.venueSearchController.hidesNavigationBarDuringPresentation = YES;
self.venueSearchController.searchBar.frame = CGRectMake(self.venueSearchController.searchBar.frame.origin.x, self.venueSearchController.searchBar.frame.origin.y, self.venueSearchController.searchBar.frame.size.width, 44.0);
self.definesPresentationContext = YES;
self.navigationController.navigationBar.translucent = YES;
self.venueSearchController.searchBar.translucent = YES;
self.tableView.tableHeaderView = self.venueSearchController.searchBar;
Run Code Online (Sandbox Code Playgroud) 我有一个实现UISearchBarDelegate的UITableVIewController,视图嵌入在导航控制器中.
class FacilityTableViewController: UITableViewController, UISearchResultsUpdating, UISearchBarDelegate, AmenityFilterDelegate {
// MARK: - Public Variables
var targetFacilities = [Int]()
var searchController: UISearchController = UISearchController(searchResultsController: nil)
// MARK: - Private Variables
private var viewModel: FacilityTableViewModel!
private let parkGreenColor = UIColor(red: 73/255, green: 136/255, blue: 84/255, alpha: 1)
private var showEmptyMessage = false
// MARK: - View Lifecycle
/**
Setup view after loading
*/
override func viewDidLoad() {
super.viewDidLoad()
trackScreenView("Facility Table View")
if targetFacilities.isEmpty {
viewModel = FacilityTableViewModel()
} else {
viewModel = FacilityTableViewModel(facilityIds: …Run Code Online (Sandbox Code Playgroud) 我试图设置searchBar为tableHeaderView内部viewDidLoad:
override func viewDidLoad() {
super.viewDidLoad()
// SearchController initializiation
self.searchController = UISearchController.init(searchResultsController: nil)
self.searchController.delegate = self
self.searchController.searchBar.delegate = self
self.searchController.searchBar.sizeToFit()
self.searchController.searchResultsUpdater = self
self.searchController.searchBar.barTintColor = UIColor.white
self.searchController.searchBar.keyboardAppearance = .default
self.searchController.searchBar.backgroundColor = UIColor.white
self.searchController.hidesNavigationBarDuringPresentation = true
self.searchController.obscuresBackgroundDuringPresentation = false
self.tableView.tableHeaderView = self.searchController.searchBar
self.definesPresentationContext = true
self.fetch()
self.tableView.reloadData()
}
Run Code Online (Sandbox Code Playgroud)
这是我的fetch()功能:
func fetch() {
let fetchRequest:NSFetchRequest<Phone> = Phone.fetchRequest()
fetchRequest.sortDescriptors = [NSSortDescriptor.init(key: "header", ascending: true), NSSortDescriptor.init(key: "date", ascending: true)]
self.fetchedResultsController = NSFetchedResultsController.init(fetchRequest: fetchRequest, managedObjectContext: self.managedObjectContext, sectionNameKeyPath: …Run Code Online (Sandbox Code Playgroud) 我试图UIRefreshControl在表视图上使用新的searchControllerAPI navigationItem.
现在,当我设置hidesSearchBarWhenScrolling"下拉刷新"动画不再显示时,刷新控件只是在某一点弹出.
它似乎是UIKit中的一个错误(与每年相同的程序).有没有人找到这个解决方案?
要重现此问题,请将其添加到全新的iOS 11"主/详细信息"示例项目中:
- (void)viewDidLoad {
// [setup code here]
self.refreshControl = [UIRefreshControl new];
self.navigationItem.searchController = [[UISearchController alloc] initWithSearchResultsController:nil];
self.navigationItem.hidesSearchBarWhenScrolling = NO; // <-- setting this causes jumpy UI
}
Run Code Online (Sandbox Code Playgroud) 我在UISearchController嵌入导航控制器的控制器中展示了一个.将出现默认动画,其中搜索框从导航栏的顶部向下滑动.
在我的情况下,这不是一个好的用户体验,因为当用户点击UITextField屏幕中间的a时,我会显示搜索.我想做的是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)
}
}
Run Code Online (Sandbox Code Playgroud)
我希望文本字段能够飞到导航栏,而不是从顶部开始搜索.我所追求的是与iOS 11 File应用程序相同的效果:
它在屏幕中间有一个文本字段,然后在点击它时动画到导航栏.但在我的情况下,文本字段在屏幕中较低,而不是导航栏的原始部分.
我遇到了UISearchController的问题,如果我在搜索栏中有文本并关闭它所在的VC,则searchBar不会消失,只是保持在屏幕上与其他VC中的所有内容重叠.如果你点击取消按钮它会崩溃.
在SO上尝试了一些解决方案,但没有一个有效.:/
self.resultSearchController = ({
let controller = UISearchController(searchResultsController: nil)
controller.searchResultsUpdater = self
controller.dimsBackgroundDuringPresentation = false
controller.hidesNavigationBarDuringPresentation = false
controller.searchBar.sizeToFit()
controller.searchBar.searchBarStyle = UISearchBarStyle.Minimal
controller.searchBar.barTintColor = UIColor(red: 243/255, green: 243/255, blue: 243/255, alpha: 1)
controller.searchBar.tintColor = UIColor.blackColor()
controller.definesPresentationContext = true
controller.edgesForExtendedLayout = UIRectEdge.None
self.tableView.contentInset = UIEdgeInsetsMake(64, 0, 0, 0)
self.tableView.tableHeaderView = controller.searchBar
return controller
})()
Run Code Online (Sandbox Code Playgroud)
非常感谢任何帮助!
更新:所以我找到了一个不太好的解决方案,即在viewWillDisappear中设置.active = false.但问题是,在完全消失之前,searchBar工件将在下一个/上一个VC上显示一秒钟.
我正在尝试创建一个这样的搜索栏:

但是我注意到我可能不得不用我自己的图像替换搜索栏,因为当我设置时,搜索栏的角落出错了:
self.searchController.searchBar.layer.cornerRadius = 50 // I've tried other numbers besides this too with no luck
self.searchController.searchBar.clipsToBounds = true
Run Code Online (Sandbox Code Playgroud)

如果我这样设置:
self.searchController.searchBar.layer.cornerRadius = self.searchController.searchBar.bounds.height/2
Run Code Online (Sandbox Code Playgroud)
搜索栏如下:

这仍然不像图像中那样精确.
有没有办法用图像替换文本字段的左侧和右侧,这样我可以使用自定义搜索栏中的圆角?
我收到以下错误.
尝试在取消分配时加载视图控制器的视图是不允许的,并且可能导致未定义的行为()
尝试了以下解决方案,但对我不起作用尝试在取消分配时加载视图控制器的视图... UISearchController
该链接提供了一个演示项目.
代码如下所示,可以从短下载的时间.
import UIKit
class DetailViewController: UIViewController,UITableViewDataSource,UITableViewDelegate,UISearchResultsUpdating,UISearchBarDelegate {
@IBOutlet weak var basicTable: UITableView!
var tblSearchController:UISearchController!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
self.tblSearchController = UISearchController(searchResultsController: nil)
self.basicTable.tableHeaderView=self.tblSearchController.searchBar
// self.tblSearchController.edgesForExtendedLayout = (UIRectEdge.Top )
// self.tblSearchController.extendedLayoutIncludesOpaqueBars = true
self.tblSearchController.searchResultsUpdater = self
self.tblSearchController.searchBar.delegate = self
self.tblSearchController.searchBar.sizeToFit()
// self.tblSearchController.searchBar.frame=CGRectMake(0, 0, self.basicTable.frame.size.width, 44.0)
self.tblSearchController.hidesNavigationBarDuringPresentation=true
self.tblSearchController.dimsBackgroundDuringPresentation=true
self.definesPresentationContext=true
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of …Run Code Online (Sandbox Code Playgroud) 我有一个表视图控制器,UISearchController其设置 UISearchBar为tableView.tableHeaderView.当更新搜索结果,我用的是beginUpdates和endUpdates和相关方法来更新表视图中的数据.
这使搜索栏消失; 将tableHeaderView其设置UIView为与搜索栏大小相同的空,通用.如果我只是使用reloadData而不是整个beginUpdates/ endUpdates程序,一切都很好.
表视图控制器嵌入在常规视图控制器中; 没有涉及导航控制器.这是重现问题所需的表视图控制器的整个实现:
- (void)viewDidLoad
{
[super viewDidLoad];
self.searchController = [[UISearchController alloc] initWithSearchResultsController:nil];
self.searchController.searchResultsUpdater = self;
self.searchController.dimsBackgroundDuringPresentation = NO;
self.tableView.tableHeaderView = self.searchController.searchBar;
}
- (void)updateSearchResultsForSearchController:(UISearchController *)searchController
{
[self.tableView beginUpdates];
[self.tableView endUpdates];
}
Run Code Online (Sandbox Code Playgroud)
为什么这会导致搜索栏被替换为空白视图,如何避免?
ios ×8
swift ×7
uisearchbar ×4
uitableview ×2
cocoa-touch ×1
core-data ×1
ios11 ×1
objective-c ×1
uikit ×1
uitextfield ×1
viewdidload ×1