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