在UISearchBar上,有一个X元素可以一次性清除所有内容。是否有一种方法可以在发生这种情况时得到通知?
UISearchBarDelegate :: searchBarCancelButtonClicked
仅在点击“取消”按钮时触发。UISearchBarDelegate :: searchBarCancelButtonClicked
仅在点击“取消”按钮时触发。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: 的调用... 显然不是最理想的方法,但在技术上可行。
我曾经遇到过同样的问题,通过使用这个函数我解决了这个问题。
- (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];
}];
}
}
这里是“方法交换”解决方案。
UISearchBar
类别。该类别创建一个新方法,并在运行时交换-(BOOL)textFieldShouldClear:(UITextField *)textField;
和-(BOOL)jbm_textFieldShouldClear:(UITextField *)textField
方法。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
参考
Dave DeLong - 如何在Cocoa中向现有协议添加方法?
Nikolay Vlasov - CCBottomRefreshControl