Pregunta

I wanted to implement a UISearchDisplayController like controller to display search results, and added some log to figure out the logic.

After I saw the logs, I am very curious about how the UISearchDisplayController steals the UISearchBar events.

UISearchDisplayController works without setting the UISearchBarDelegate to itself. And the UISearchBarDelegate is working at the same time outside!

Here are the logs:

searchBarShouldBeginEditing:

searchBarTextDidBeginEditing:

searchDisplayControllerWillBeginSearch:

searchDisplayController:didLoadSearchResultsTableView:

searchBar:shouldChangeTextInRange:replacementText:

searchBar:textDidChange:

searchDisplayController:shouldReloadTableForSearchString:

searchDisplayController:willShowSearchResultsTableView:

searchDisplayController:didShowSearchResultsTableView:

searchBarCancelButtonClicked:

searchBarShouldEndEditing:

searchBarTextDidEndEditing:

searchDisplayController:willHideSearchResultsTableView:

searchDisplayController:didHideSearchResultsTableView:

searchBarShouldBeginEditing:

searchBarTextDidBeginEditing:

searchDisplayControllerWillBeginSearch:

searchBar:shouldChangeTextInRange:replacementText:

searchBar:textDidChange:

searchDisplayController:shouldReloadTableForSearchString:

searchDisplayController:willShowSearchResultsTableView:

searchDisplayController:didShowSearchResultsTableView:

searchBar:shouldChangeTextInRange:replacementText:

searchBarSearchButtonClicked:

searchBarShouldEndEditing:

searchBarTextDidEndEditing:

searchBarCancelButtonClicked:

searchDisplayController:willHideSearchResultsTableView:

searchDisplayController:didHideSearchResultsTableView:

¿Fue útil?

Solución

OK, I figured out myself.

You can do that just by adding the UISearchBar delegate property to KVO observation, and then make your implementation as a delegate proxy.

Example Code:


    if (searchBar.delegate) {
        self.searchBarDelegate = searchBar.delegate;
    }

    searchBar.delegate = self;

    [searchBar addObserver:self forKeyPath:@"delegate" options:NSKeyValueObservingOptionNew context:kSearchBarKVOContext];

#pragma mark - KVO
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
{
    if (context == kSearchBarKVOContext) {
        [self updateSearchBarDelegate];
    } else {
        [super observeValueForKeyPath:keyPath ofObject:object change:change context:context];
    }
}

- (void)updateSearchBarDelegate
{
    if (self.searchBar.delegate == self) {
        self.searchBarDelegate = nil;
    } else {
        self.searchBarDelegate = self.searchBar.delegate;
        self.searchBar.delegate = self;
    }
}

#pragma mark - NSObject Overrides
- (NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector
{
    NSMethodSignature *result = [super methodSignatureForSelector:aSelector];

    if (!result) {
        NSObject *obj = (NSObject *)self.searchBarDelegate;

        result = [obj methodSignatureForSelector:aSelector];
    }

    return result;
}

- (void)forwardInvocation:(NSInvocation *)anInvocation
{
    if ([self.searchBarDelegate respondsToSelector:[anInvocation selector]]) {
        [anInvocation invokeWithTarget:self.searchBarDelegate];
    } else {
        [super forwardInvocation:anInvocation];
    }
}

- (BOOL)respondsToSelector:(SEL)aSelector {
    return ([super respondsToSelector:aSelector] ||
            [self.searchBarDelegate respondsToSelector:aSelector]);
}
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top