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.