My finish objective is to have the ability to have constant search expertise throughout each iPhone and iPad.
The expertise I’m after is to set off the UISearchResultsController
on a bar button faucet slightly than exhibiting the search bar within the UINavigationBar
One thing like this:
What I’ve completed to realize this:
#1 – I name the next code from my View Controller so as to initialize a UISearchResultsController
however conceal the search bar initially and set off it utilizing a bar button merchandise
// Known as from viewDidLoad
personal func configureSearchExperience() {
let picture = UIImage(named: "searchIconName")
searchController = createSearchController()
searchController?.searchBar.placeholder = searchPlaceHolder
searchController?.searchBar.setImage(picture, for: .search, state: .regular)
searchController?.searchBar.autocapitalizationType = .none
searchController?.searchBar.isHidden = true
navigationItem.searchController = nil
navigationItem.hidesSearchBarWhenScrolling = false
}
personal func createSearchController() -> UISearchController {
let viewController = UIHostingController(rootView: SearchResultsSwiftUIView())
let search = CustomSearchController(searchResultsController: viewController)
search.delegate = self
search.showsSearchResultsController = true
search.obscuresBackgroundDuringPresentation = true
search.searchBar.delegate = self
return search
}
// Known as from viewDidLoad
personal func addBarButtons() {
let settingsButton = createButton(imageName: settingsIconName,
motion: #selector(showSettings),
accessibilityLabel: viewModel.settingsAccessibilityIdentifier)
let searchButton = createButton(imageName: searchOutlineIconName,
motion: #selector(launchSearchExperience),
accessibilityLabel: viewModel.searchAccessibilityIdentifier)
let stackView = UIStackView(arrangedSubviews: [searchButton, settingsButton])
stackView.axis = .horizontal
stackView.spacing = viewModel.barButtonInterItemSpacing
navigationItem.rightBarButtonItem = UIBarButtonItem(customView: stackView)
}
personal func createButton(imageName: String, motion: Selector, accessibilityLabel: String) -> UIButton {
let button = UIButton(sort: .system)
if let picture = UIImage(named: imageName)?.withRenderingMode(.alwaysOriginal) {
button.setImage(picture, for: .regular)
}
button.addTarget(self, motion: motion, for: .touchUpInside)
button.accessibilityLabel = accessibilityLabel
return button
}
@objc func launchSearchExperience() {
navigationItem.searchController = searchController
// A brief delay prevents occasional UI glitches when activating the search controller instantly after including it
// to the navigation merchandise. The 0.1s delay is an empirically chosen worth that balances responsiveness and stability.
// It was additionally urged in: https://stackoverflow.com/q/27951965/1619193
let searchActivationDelay = 0.1
DispatchQueue.foremost.asyncAfter(deadline: .now() + searchActivationDelay) { [weak self] in
self?.searchController?.isActive = true
self?.searchController?.becomeFirstResponder()
}
}
#2 – That is the customized SearchResultsController accountable to point out the search bar ONLY when the UISearchResultsController is activated:
class CustomSearchController: UISearchController {
override func viewWillAppear(_ animated: Bool) {
tremendous.viewWillAppear(animated)
searchBar.isHidden = false
searchBar.becomeFirstResponder()
}
override func viewWillDisappear(_ animated: Bool) {
tremendous.viewWillDisappear(animated)
searchBar.isHidden = true
}
}
Collectively this offers me the expertise I need for probably the most half on iPhones, nevertheless, on iPad, it will get damaged within the state of affairs once I go to the element view from one of many search outcomes after which swipe to return again, right here is an illustration of this:
#1 – We begin the icon within the nav bar
#2 – Search outcomes controller is activated
#3 – Getting back from particulars display screen display screen messes this up
#4 – Slowing the swipe again animation reveals it’s advantageous until the final second after which breaks
iPhone doesn’t have this situation and if I faucet again and return, we do not need this situation.
Solely once I swipe to return again, we have now this situation.
Any concept what might be unsuitable.