iOS 11 UISearchBar in UINavigationBar
Now it's what you want...
if #available(iOS 11.0, *) {
let sc = UISearchController(searchResultsController: nil)
sc.delegate = self
let scb = sc.searchBar
scb.tintColor = UIColor.white
scb.barTintColor = UIColor.white
if let textfield = scb.value(forKey: "searchField") as? UITextField {
textfield.textColor = UIColor.blue
if let backgroundview = textfield.subviews.first {
// Background color
backgroundview.backgroundColor = UIColor.white
// Rounded corner
backgroundview.layer.cornerRadius = 10;
backgroundview.clipsToBounds = true;
}
}
if let navigationbar = self.navigationController?.navigationBar {
navigationbar.barTintColor = UIColor.blue
}
navigationItem.searchController = sc
navigationItem.hidesSearchBarWhenScrolling = false
}
Result:
With Rounded corner:
Animation with rounded corner is also working fine.
Broken UISearchBar animation embedded in NavigationItem
It looks like Apple still needs to iron out the use of the UISearchBar in the new large title style. If the UIViewController
you push to doesn't have its navigationItem.searchController
set, the animation works fine. When navigating between two instances of UIViewController
that both have a searchController set, you get the issue you describe where the height of the navigation bar jumps.
You can solve (work around) the problem by creating the UISearchController
every time viewDidAppear
gets called (instead of creating it in loadView
) and setting navigationItem.searchController
to nil on viewDidDisappear
.
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
DispatchQueue.main.async {
let stvc = UITableViewController()
stvc.tableView.dataSource = self
let sc = UISearchController(searchResultsController: stvc)
sc.searchResultsUpdater = self
self.navigationItem.searchController = sc
}
}
override func viewDidDisappear(_ animated: Bool) {
super.viewDidDisappear(animated)
self.navigationItem.searchController = nil
}
The reason for the asynchronous dispatch is that when setting the navigationItem.searchController
inline in the viewDidAppear
method, an exception is raised:
Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Only one palette with a top boundary edge can be active outside of a transition. Current active palette is <_UINavigationControllerManagedSearchPalette: 0x7fad67117e80; frame = (0 116; 414 0); layer = <CALayer: 0x60400002c8e0>>'
I know this is only a work around, but hopefully this will help you for now, until Apple solves the issue with navigating between two view controllers that both have a UISearchController
set on their navigationItem
.
Related Topics
How to Check If a String Contains Letters in Swift
How in Swift to Convert Int16 to Two Uint8 Bytes
Swift Calling Static Methods: Type(Of: Self) VS Explicit Class Name
Difference Between Packed VS Normal Data Type
How to Create Type Erasing Weak References with Non-Optional Properties in Swift
How to Draw a Scnnode Always in Front of Others
Nsurlsession/Nsurlconnection Http Load Failed (Kcfstreamerrordomainssl, -9802)
Easiest Way to Find Square Root in Swift
How to Avoid Using Anypublisher/Erasetoanypublisher All Over the Place
Check Availability in Switch Statement
Swift Error When Trying to Access Dictionary: 'Could Not Find Member 'Subscript''
Swift Check Type Against a Generic Type
Unsafemutablepointer<Uint8> to [Uint8] Without Memory Copy
Uisplitviewcontroller in Portrait on iPhone Always Show Master and Detail in iOS 8