9

在 UISearchBar 上有一个 X 元素,可让您一次清除所有内容。有没有办法在发生这种情况时得到通知?

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

4

4 回答 4

7

UISearchBar没有此事件的委托方法。textDidChange:通过实现回调委托的方法并检查空字符串,您几乎可以得到您想要的。

我不推荐它,但还有另一种可能的方法。它UISearchBar由一个 UITextField 组成,它确实有一个委托方法,当用户点击清除按钮 ( textFieldShouldClear:) 时会调用该委托方法。您可以UITextField通过遍历UISearchBar的子视图来获得:

(这是在派生UISearchBar类的上下文中)

- (UIView*) textField
{
    for (UIView* v in self.subviews)
    {
        if ( [v isKindOfClass: [UITextField class]] )
            return v;
    }

    return nil;
}

从这里,您可以将委托重新分配UITextField给您自己的实现,注意将委托调用转发给旧委托。这样你就可以拦截textFieldShouldClear:. 或者,如果结果UISearchBar是它包含的委托,UITextField您可以调整对 textFieldShouldClear:... 的调用。显然,这并不理想,但在技术上是可行的。

于 2010-11-08T05:17:30.183 回答
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];
       }];
    }
}
于 2014-05-21T18:20:52.193 回答
1

这是上一个问题的答案,这应该完全符合您的要求。UISearchbar clearButton 强制键盘出现

于 2010-11-16T04:50:38.450 回答
0

这是“Method Swizzling”解决方案。

  1. 创建一个新的类别UISearchBar-(BOOL)textFieldShouldClear:(UITextField *)textField;此类别在运行时之间和运行时创建新方法和 swizzle 方法-(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

于 2016-01-08T08:05:35.750 回答