UISearchController: searchBar and scopeBar overlap

2020-06-06 01:34发布

I'm trying to implement a simple search bar using Apple's latest UISearchController. However I can't seem to get it to work correctly if I use the search bar's scope bar to get a filter choice.

The scope bar always shows which I could live with at startup scope bar always shows

but on the very first touch event the search bar and scope bar overlap. Search bar and scopebar collapse

I used Apple's TableView sample code app but it didn't change anything.

- (void)viewDidLoad {
[super viewDidLoad];

_resultsTableController = [[APLResultsTableController alloc] init];
_searchController = [[UISearchController alloc] initWithSearchResultsController:self.resultsTableController];
self.searchController.searchResultsUpdater = self;
[self.searchController.searchBar sizeToFit];
self.searchController.searchBar.showsScopeBar = YES;
[self.searchController.searchBar setScopeButtonTitles:@[@"First",@"Second"]];
self.tableView.tableHeaderView = self.searchController.searchBar;

// we want to be the delegate for our filtered table so didSelectRowAtIndexPath is called for both tables
self.resultsTableController.tableView.delegate = self;
self.searchController.delegate = self;
self.searchController.dimsBackgroundDuringPresentation = NO; // default is YES
self.searchController.searchBar.delegate = self; // so we can monitor text changes + others

// Search is now just presenting a view controller. As such, normal view controller
// presentation semantics apply. Namely that presentation will walk up the view controller
// hierarchy until it finds the root view controller or one that defines a presentation context.
//
self.definesPresentationContext = YES;  // know where you want UISearchController to be displayed

}

I implemented the search bar's delegate methods as well but it just switches the timing of the overlap.

Has anyone been able to implement a search bar using iOS 8s UISearchController and using the searchBar's scope bar?

Thanks in advance

3条回答
We Are One
2楼-- · 2020-06-06 01:46

I just spent three days working on this same issue going through all of the posts I could find and just finally found the solution on the Apple Dev forum so thought I would post an update to help the next person that encounters this issue.

The resolution is to make sure that the showsScopeBar property on the search bar belonging to a UISearchController is set to false, i.e. UISearchController.searchBar.showsScopeBar = false in Swift.

The issue seems to be that Apple's design intent is for the showsScopeBar property to be used with standalone search bars not search bars controlled by a UISearchController. Unfortunately this is not called out in the class documentation. Bad design decision in my opinion but it is what it is.

The discussion is in the following thread https://devforums.apple.com/thread/235803 (dead link as of 2018-01-26).

Best of luck.

查看更多
女痞
3楼-- · 2020-06-06 02:10

This appears to be a known defect. There are several radr entries such as http://www.openradar.me/20702394 that refer to similar issues and a workaround by using sizeToFit()

The workaround they suggest works, but only when it was applied within viewDidLayoutSubviews. i.e. after all of the views were laid out.

override func viewDidLayoutSubviews() {
    self.searchController.searchBar.sizeToFit()
}
查看更多
Luminary・发光体
4楼-- · 2020-06-06 02:12

Update for swift 3:

searchController.searchBar.showsScopeBar = false

Update for swift 4:

It seems that in swift 4 and ios 11 the search bar got changed. With the method showed above the scope bar will be inside the search bar in some cases.

if #available(iOS 11.0, *) {
        navigationItem.searchController = searchController
        navigationItem.hidesSearchBarWhenScrolling = false
    } else {
        tableView.tableHeaderView = searchController.searchBar
    }

This fixed it for me. I use the the form shown above if ios 10 is available. If ios 11 is available i change my technic and set the navigation view controller to the search controller. You will notice it looks exactly as on ios 10

查看更多
登录 后发表回答