问题
I have an app which works nice and without any problems on iOS 10 but with iOS 11 and Xcode Beta 5, I have this strange problem with search bar scope where the scope bar seems like it was cut from the bottom. (It was the same with all versions of Xcode beta and iOS 11) I would really really be glad if someone can put me in the right direction. Thanks
Above you can see what I see when I press the hamburger menu button. No problem here.. searchbar also has a scopebar which shows up when clicked on.I did not set it to show up programatically.But I guess this is its default behaviour when scope button titles are set.
The Problem:
When I click on the searchbar to enter information I see the screen above. On iOS 10 I had no problems. But now, with iOS 11, whatever I do I just cannot make it work like it works on iOS 10. Search scope bar shows up like it was cut from the bottom.
This is how it shows up in iOS 10 and I want it to be in iOS 11.
Storyboard view of the screen
I am pasting the relevant code here.
class SlideMenuViewController: UIViewController,UITableViewDelegate,UITableViewDataSource,UISearchControllerDelegate,UIGestureRecognizerDelegate{
let searchController = UISearchController(searchResultsController: nil)
@IBOutlet var sview: UIView!
@IBOutlet var tableView: UITableView!
override func viewWillAppear(_ animated: Bool) {
//some non relevant code before this
if sview.subviews .contains(searchController.searchBar) {
print("Already contains")
} else {
sview.addSubview(searchController.searchBar)
print(searchController.searchBar.showsScopeBar)
searchController.searchBar.sizeToFit()
searchController.searchBar.frame.size.width = view.frame.size.width
searchController.searchBar.barTintColor = searchBarTintColor
searchController.searchBar.tintColor = searchTintColor
}
}
override func viewDidLoad() {
//some other code
searchController.searchBar.delegate = self
searchController.searchBar.scopeButtonTitles = [NSLocalizedString("İsimlerde", comment: ""), NSLocalizedString("Açıklamalarda", comment: "")]
searchController.searchBar.returnKeyType = UIReturnKeyType.done
searchController.searchResultsUpdater = self
searchController.dimsBackgroundDuringPresentation = false
definesPresentationContext = true
//some other code
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
if searchController.isActive && searchController.searchBar.text != "" {
switch scpglobal {
case NSLocalizedString("İsimlerde", comment: ""):
return filteredIsimler.count
case NSLocalizedString("Açıklamalarda", comment: ""):
return filteredAciklamalar.count
default:
print("Tableview default")
}
}
return isimlerArray.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
//some code about search here but nothing that will result in that behaviour
}
func searchBarCancelButtonClicked(_ searchBar: UISearchBar) {
print("cancel")
searchController.searchBar.text = ""
}
func updateSearchResults(for searchController: UISearchController) {
let searchBar = searchController.searchBar
let scope = searchBar.scopeButtonTitles![searchBar.selectedScopeButtonIndex]
filterContentForSearchText(searchText: searchController.searchBar.text!, scope: scope)
tableView.reloadData()
}
}
extension SlideMenuViewController:UISearchBarDelegate {
func searchBar(_ searchBar: UISearchBar, selectedScopeButtonIndexDidChange selectedScope: Int) {
filterContentForSearchText(searchText: searchController.searchBar.text!, scope: searchController.searchBar.scopeButtonTitles![selectedScope])
}
}
Edit: This is what happens if I add constraints to search bar. First everything seems good.
Then when you click on search bar this happens..Search bar moves out of the screen. See the arrow.
But if you close the sliding menu and re-open it then
Everything works OK until you click the cancel button. After that you have to do all this again to see the search bar working.
Code for the constraints
searchController.searchBar.translatesAutoresizingMaskIntoConstraints = false
sview.addConstraint(NSLayoutConstraint(item: searchController.searchBar, attribute: .top, relatedBy: .equal, toItem: sview, attribute: .top, multiplier: 1, constant: 0))
sview.addConstraint(NSLayoutConstraint(item: searchController.searchBar, attribute: .bottom, relatedBy: .equal, toItem: sview, attribute:.bottom, multiplier: 1, constant: 0))
sview.addConstraint(NSLayoutConstraint(item: searchController.searchBar, attribute: .leading, relatedBy: .equal, toItem: sview, attribute: .leading,multiplier: 1, constant: 0))
sview.addConstraint(NSLayoutConstraint(item: searchController.searchBar, attribute: .trailing, relatedBy: .equal, toItem: sview, attribute: .trailing, multiplier: 1, constant: 0))
回答1:
Check out this WWDC 2017 video.
You should do something like this:
if #available(iOS 11.0, *) {
navigationItem.searchController = searchController
navigationItem.hidesSearchBarWhenScrolling = false
} else {
tableView.tableHeaderView = searchController.searchBar
}
and then do the changes you need accordingly.
回答2:
I was able to resolve the issue by replacing searchController
with a custom searchBar
.
let searchBar = UISearchBar(frame:CGRect(x: 0, y: 0, width: 266, height: 100))
Be careful though, do not forget to use
searchBar.sizeToFit
inside searchBarShouldBeginEditing
and searchBarShouldEndEditing
or else you might have strange UI problems especially if you are using the
searchBar.showsScopeBar = true
so, if you are having a similar problem, get rid of the searchController
and implement a searchBar
and its delegate methods. It will not give you the same scopeBar animation but at least it works. Another downside for this method is, if you have the searchBar.isTranslucent = true
you might see the ghost of another scopeBar inside the searchBar. So make sure that
searchBar.isTranslucent = false
If anyone comes up with a better way to solve this problem, I am all ears...
Sample Delegate Setup
func searchBarShouldBeginEditing(_ searchBar: UISearchBar) -> Bool {
searchBar.showsScopeBar = true
searchBar.sizeToFit()
searchBar.setShowsCancelButton(true, animated: true)
return true
}
func searchBarShouldEndEditing(_ searchBar: UISearchBar) -> Bool {
searchBar.showsScopeBar = false
searchBar.sizeToFit()
searchBar.setShowsCancelButton(false, animated: true)
return true
}
回答3:
This might solve your problem:
func searchDisplayController(_ controller: UISearchController, willShowSearchResultsTableView tableView: UITableView)
{
tableView.backgroundColor = self.tableView.backgroundColor
tableView.rowHeight = self.tableView.rowHeight
tableView.tableFooterView = UIView()
}
来源:https://stackoverflow.com/questions/45782669/swift-4-ios-11-search-bar-scope-wont-appear-as-it-should