문제

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:

도움이 되었습니까?

해결책

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]);
}
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top