UISearchBarDelegate でインクリメンタルサーチ用のテキスト入力検知


UISearchBarDelegate を使ってインクリメンタルサーチをするためのテキスト入力検知を実装してみたので、その備忘録。
日本語の入力はちょっと怪しい。(濁音、半濁音とか)
細かくテストはしていないので、バグがあるかもしれません。

- (void)searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText
{
    // ここでは空文字列検索はしない
    if (![searchText isEqualToString:@""]) {
        NSLog(@"keyword: %@", searchText);
        [self searchKeyword:searchText];
    }
}

- (BOOL)searchBar:(UISearchBar *)searchBar shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text
{
    NSLog(@"%@, %@, len:%@, loc:%@", searchBar.text, text, @(range.length), @(range.location));
    BOOL isFirstCharacter = (range.location == 0 && range.length == 0);
    BOOL isDeleteText = ([text isEqualToString:@""] && range.length > 0);
    BOOL isInputtingText = (![searchBar.text isEqualToString:@""] && ![text isEqualToString:@""]);
    BOOL hasNotEnterdYet = (isInputtingText && range.length == 0);
    if (isFirstCharacter || isDeleteText || hasNotEnterdYet) {
        [self searchKeyword:[self replceKeyword:searchBar.text
                                          range:range
                                     withString:text]];
        return YES;
    }
    return YES;
}

- (nonnull NSString *)replceKeyword:(nonnull NSString *)keyword
                              range:(NSRange)range
                         withString:(nonnull NSString *)string
{
    NSParameterAssert(keyword);
    NSParameterAssert(string);
    NSMutableString *result = [keyword mutableCopy];
    BOOL isDeleteText = [string isEqualToString:@""];
    if (isDeleteText) {
        [result replaceCharactersInRange:range withString:string];
    } else {
        [result insertString:string atIndex:range.location];
    }
    NSLog(@"keyword: %@", result);
    return result;
}

- (void)searchKeyword:(nonnull NSString *)keyword
{
    // Search API
}

Documents