How does UISearchController do everything it does?
UISearchBar into a navigation-bar-like view?UISearchBar into another view hierarchy and restore it later?UIViewController presentation API?Can I make my own UISearchController without using private APIs?
The UISearchController was introduced a couple years ago in iOS 8 to replace the now deprecated UISearchDisplayController. In the new search controller, it is easier to add search to your table views.
Hopefully you found that it was not too much work to add a UISearchController. Once Apple updates Interface Builder to include the UISearchController, it should be even less code.
Provide a UISearchResultsUpdating object to the search controller’s searchResultsUpdater property. Typically, the view controller with your searchable content also acts as the search results updater object, but you can use another object if you prefer.
You need a UISearchBar. If you look at UISearchController ‘s documentation, you’ll discover it’s pretty lazy. It doesn’t do any of the work of searching at all. The class simply provides the standard interface that users have come to expect from their iOS apps.
UISearchController creates a UISearchBar and in its internal _connectSearchBar method it calls a private method on UISearchBar _setSearchController. Then in the UISearchBar's internal event methods, e.g. _searchFieldBeginEditing it first calls its public delegate method and then [__searchController _searchBarTextDidBeginEditing:] to allow the controller to also process the event. This is what enables the feature "you free to become the UISearchBar's delegate".
Similarly, in UISearchBar's text field begin editing it calls UISearchController's _searchBarTextDidBeginEditing which calls _performAutomaticPresentation which uses the transition coordinator to animate the presentation.
In the UISearchBar's didMoveToSuperView it calls [__searchController _searchBarSuperviewChanged] which first checks if its searchBar has been put on a UITableView and if so it configures its background colours, insets etc. for viewing.
Yes you could architect this all yourself, but not by subclassing UISearchBar as you'd do in Java, instead of inheritance which can get complex use ObjC's delegation pattern which enables a flatter class hierarchy. E.g. you'd have a controller class that take a UISearchBar in its init method, sets itself as its delegate, then uses delegate forwarding to allow the existing delegate methods to still get called to the outside public delegate. Here is an example except for a table view:
- (instancetype)initWithTableView:(UITableView *)tableView{
self = [super init];
if (self) {
tableView.delegate = self;
_tableView = tableView;
}
return self;
}
- (id)forwardingTargetForSelector:(SEL)aSelector{
if(MHFProtocolHasInstanceMethod(@protocol(UITableViewDelegate), aSelector)){
if([self.tableViewDelgate respondsToSelector:aSelector]){
return self.tableViewDelgate;
}
}
return [super forwardingTargetForSelector:aSelector];
}
-(void)tableView:(UITableView *)tableView didEndEditingRowAtIndexPath:(NSIndexPath *)indexPath{
if([self.tableViewDelgate respondsToSelector:_cmd]){
return [self.tableViewDelgate tableView:tableView didEndEditingRowAtIndexPath:indexPath];
}
[self performSelector:@selector(updateSelectionForCurrentVisibleDetailItem) withObject:nil afterDelay:0];
}
The point of this pattern is subclasses of your controller are no longer required to call super to ensure everything still works as expected without the programmer being required to call super. Also it makes for much more reusable classes since it can work with any kind of search bar.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With