UISearchBar和在点击“X”元素时触发的事件

9
在UISearchBar上,有一个X元素可以一次性清除所有内容。是否有一种方法可以在发生这种情况时得到通知?

UISearchBarDelegate :: searchBarCancelButtonClicked仅在点击“取消”按钮时触发。

https://dev59.com/TV4b5IYBdhLWcg3wchNL#59105874 :)(注:这是一个表情符号,无需翻译) - Mohan
4个回答

7
UISearchBar没有针对此事件的委托方法。您可以通过实现回调委托的textDidChange:方法并检查空字符串来几乎获得所需内容。
我不建议这样做,但还有另一种可能的方法。 UISearchBar由一个UITextField组成,该UITextField具有在用户点击清除按钮(textFieldShouldClear:)时调用的委托方法。您可以通过遍历UISearchBar的子视图来获取UITextField
(这是在派生的UISearchBar类的上下文中)
- (UIView*) textField
{
    for (UIView* v in self.subviews)
    {
        if ( [v isKindOfClass: [UITextField class]] )
            return v;
    }

    return nil;
}

从这里开始,您可以重新分配 UITextField 的委托以使用自己的实现,并注意将委托调用转发到旧的委托。这样,您就可以拦截 textFieldShouldClear:。或者,如果 UISearchBar 是包含 UITextField 的委托,则可以交换对 textFieldShouldClear: 的调用... 显然不是最理想的方法,但在技术上可行。


为什么您不建议实现textDidChange并检查空字符串? - Justin Galzic
我认为这是一个不错的方法。但它并不完全符合他的要求,因为文本可能以其他方式变为空字符串,而不仅仅是通过点击“x”。比如说退格键...所以如果他想在每次单击“x”时得到通知,那么这将导致错误的结果。 - TomSwift

2

我曾经遇到过同样的问题,通过使用这个函数我解决了这个问题。

- (void)searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText 
{
    // This method has been called when u enter some text on search or Cancel the search.
    if([searchText isEqualToString:@""] || searchText==nil) {
        // Nothing to search, empty result.

       [UIView animateWithDuration:0.2 animations:^ {
        //Reposition search bar 
        [_searchBar setFrame:CGRectMake(230, 26, 43, 44)];
        [_searchBar setNeedsLayout];
       }];
    }
}

1

0

这里是“方法交换”解决方案。

  1. 创建一个新的UISearchBar类别。该类别创建一个新方法,并在运行时交换-(BOOL)textFieldShouldClear:(UITextField *)textField;-(BOOL)jbm_textFieldShouldClear:(UITextField *)textField方法。
  2. 自定义一个新的UISearchBarDelegate协议,以添加一个新方法- (void)searchBarClearButtonClicked:(id)sender;

UISearchBar+JMBTextFieldControl.h

    @protocol UISearchBarWithClearButtonDelegate <UISearchBarDelegate>
    @optional
    - (void)searchBarClearButtonClicked:(id)sender;
    @end

    @interface UISearchBar (JMBTextFieldControl)
    @end

UISearchBar+JMBTextFieldControl.m

    #import "UISearchBar+JMBTextFieldControl.h"
    #import <objc/runtime.h>

    @implementation NSObject (Swizzling)

    + (void)brc_swizzleMethod:(SEL)origSelector withMethod:(SEL)newSelector
    {
        Method origMethod = class_getInstanceMethod(self, origSelector);
        Method newMethod = class_getInstanceMethod(self, newSelector);

        if(class_addMethod(self, origSelector, method_getImplementation(newMethod), method_getTypeEncoding(newMethod)))
            class_replaceMethod(self, newSelector, method_getImplementation(origMethod), method_getTypeEncoding(origMethod));
        else
            method_exchangeImplementations(origMethod, newMethod);
    }
    @end

    @implementation UISearchBar (JMBTextFieldControl)

    + (void)load {
        [self brc_swizzleMethod:@selector(textFieldShouldClear:) withMethod:@selector(jbm_textFieldShouldClear:)];
    }

    - (id<UISearchBarWithClearButtonDelegate>)jbm_customDelegate {
        if( [[self delegate] conformsToProtocol:@protocol(UISearchBarWithClearButtonDelegate)] )
            return (id<UISearchBarWithClearButtonDelegate>)[self delegate];
        else
            return nil;
    }

    - (BOOL)jbm_textFieldShouldClear:(UITextField *)textField
    {
        if ( [[self jbm_customDelegate] respondsToSelector:@selector(searchBarClearButtonClicked:)] )
            [[self jbm_customDelegate] searchBarClearButtonClicked:self];

        return [self jbm_textFieldShouldClear:textField];
    }

    @end

参考

  1. Dave DeLong - 如何在Cocoa中向现有协议添加方法?

  2. Nikolay Vlasov - CCBottomRefreshControl


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接