iOS 11 search bar jumping to top of screen
It is encouraged to apply the new way to show search bar/search controller on iOS 11.
Here is what I have done:
if #available(iOS 11.0, *) {
navigationItem.searchController = searchController
} else {
tableView.tableHeaderView = searchController.searchBar
}
iOS 11 search bar in tableViewHeader jumps to the top of the screen on focus
Since iOS11, search control is part of navigation bar. You will need something like the following
Objective-C
if (@available(iOS 11.0, *)) {
self.navigationItem.searchController = searchController
} else {
self.tableView.tableHeaderView = searchController.searchBar
}
Swift
if #available(iOS 11.0, *) {
Search bar overlaps with status bar on iOS 11
I found that the problem was that the presenting view Controller also sets
override open func viewDidLoad() {
super.viewDidLoad()
self.edgesForExtendedLayout = [];
self.automaticallyAdjustsScrollViewInsets = false;
}
I have to do this because the table view does not actually extend all the way to the top.
I solved this like that in my presenting view Controller:
override open func viewDidLoad() {
super.viewDidLoad()
self.automaticallyAdjustsScrollViewInsets = false;
if (@available(iOS 11.0, *)) {
//NSLog(@"iOS 11.0");
} else {
self.edgesForExtendedLayout = UIRectEdgeNone;
//NSLog(@"iOS < 11.0");
}
}
Seems to be an iOS 11 bug, or at least an odd behavior…
UISearchBar jumping out of position once tapped
The solution I used was to subclass the UISearchBar
and the UISearchController
. That way I can set the frame and control the search bar events.
SearchBar.swift
:
import Foundation
class SearchBar : UISearchBar {
var preferredFont:UIFont?
var preferredTextColor:UIColor?
init(frame: CGRect, font: UIFont, textColor: UIColor) {
super.init(frame: frame)
self.frame = frame
self.preferredFont = font
self.preferredTextColor = textColor
}
required init(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)!
}
}
SearchController.swift
:
import Foundation
protocol SearchControllerDelegate {
func didStartSearching()
func didTapOnSearchButton()
func didTapOnCancelButton()
func didChangeSearchText(searchText: String)
}
class SearchController : UISearchController, UISearchBarDelegate, SearchControllerDelegate {
var customSearchBar: SearchBar!
var customDelegate: SearchControllerDelegate!
init(searchResultsController: UIViewController!, searchBarFrame: CGRect, searchBarFont: UIFont, searchBarTextColor: UIColor, searchBarTintColor: UIColor) {
super.init(searchResultsController: searchResultsController)
configureSearchBar(frame: searchBarFrame, font: searchBarFont, textColor: searchBarTextColor, bgColor: searchBarTintColor)
}
override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: Bundle?) {
super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil)
}
required init(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)!
}
func configureSearchBar(frame: CGRect, font: UIFont, textColor: UIColor, bgColor: UIColor) {
self.customSearchBar = SearchBar(frame: frame, font: font , textColor: textColor)
self.customSearchBar.placeholder = "Search"
self.customSearchBar.barTintColor = bgColor
self.customSearchBar.tintColor = textColor
self.customSearchBar.showsBookmarkButton = false
self.customSearchBar.showsCancelButton = false
self.customSearchBar.delegate = self
self.customDelegate = self;
let searchBarTextField:UITextField = self.customSearchBar.value(forKey: "searchField") as! UITextField
searchBarTextField.font = font
searchBarTextField.layer.borderWidth = 1
searchBarTextField.layer.cornerRadius = 3
searchBarTextField.layer.borderColor = UIColor.lightGray.cgColor
}
// UISearchBarDelegate
func searchBarTextDidBeginEditing(_ searchBar: UISearchBar) {
customDelegate.didStartSearching()
}
func searchBarSearchButtonClicked(_ searchBar: UISearchBar) {
customSearchBar.resignFirstResponder()
customDelegate.didTapOnSearchButton()
}
func searchBarCancelButtonClicked(_ searchBar: UISearchBar) {
customSearchBar.resignFirstResponder()
customDelegate.didTapOnCancelButton()
}
func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) {
customDelegate.didChangeSearchText(searchText: searchText)
}
// SearchControllerDelegate
func didStartSearching() {
}
func didTapOnSearchButton() {
var searchText:String = ""
if (self.customSearchBar.text != nil) {
searchText = self.customSearchBar.text!
}
self.search(searchQuery: searchText)
}
func didTapOnCancelButton() {
}
func didChangeSearchText(searchText: String) {
self.search(searchQuery: searchText)
}
// Search
func search(searchQuery: String) {
// Start searching
}
}
UISearchController's UISearchBar shifts incorrectly and jumps when UITableView is scrolled
What you have done is correct. Did you try running your code in a device? Feels more like a glitch in the simulator. I tried what you tried and it works fine for me in the device. Whereas the glitch occurs in simulator.
Refer to this article. They have explained step by step process.
Related Topics
iPad 3 - Opengl Bug with Keagldrawablepropertyretainedbacking and Retina
Instantiateviewcontrollerwithidentifier - Storyboard Id Set But Still Not Working
Remove Uiwebview's Internal Cache
Nspredicate Filtered by Year Moth Day
Open Uiimagepickercontroller in Landscape Mode
Rotate Image Using Cgcontextdrawimage
Getting the Action of Uigesturerecognizer in iOS
How to Send a Uilongpressgesture Programmatically
How to Get Nsdate with Millisecond Accuracy
Avplayer Uitapgesturerecognizer Not Working
Downcast from Any to a Protocol
iOS Notification When Application Is Closed
Uiview Drawrect: Draw the Inverted Pixels, Make a Hole, a Window, Negative Space
Chrome for iOS User Agent on iPad