On the UISearchBar, there's an X element that allows you to clear all of the contents at once. Is there a way to get notified when this happens?
在UISearchBar上,有一个X元素允许您一次清除所有内容。有没有办法在发生这种情况时收到通知?
UISearchBarDelegate::searchBarCancelButtonClicked
is fired only when the "Cancel" button is tapped.
只有在点击“取消”按钮时才会触发UISearchBarDelegate :: searchBarCancelButtonClicked。
4 个解决方案
#1
7
The UISearchBar
doesn't have a delegate method for this event. You can nearly get what you want by implementing the textDidChange:
method of the callback delegate and checking for an empty string.
UISearchBar没有此事件的委托方法。通过实现回调委托的textDidChange:方法并检查空字符串,您几乎可以获得所需的内容。
I don't recommend it, but there is another possible way. The UISearchBar
is composed of a UITextField, which does have a delegate method that is called when the user taps the clear button (textFieldShouldClear:
). You can get the UITextField
by traversing the UISearchBar
's child views:
我不推荐它,但还有另一种可能的方法。 UISearchBar由一个UITextField组成,它有一个委托方法,当用户点击clear按钮(textFieldShouldClear :)时会调用该方法。您可以通过遍历UISearchBar的子视图来获取UITextField:
(this is in the context of a derived UISearchBar
class)
(这是在派生的UISearchBar类的上下文中)
- (UIView*) textField
{
for (UIView* v in self.subviews)
{
if ( [v isKindOfClass: [UITextField class]] )
return v;
}
return nil;
}
from here, you could re-assign the UITextField
delegate to your own implementation, taking care to forward delegate calls to the old delegate. This way you could intercept textFieldShouldClear:
. Or if it turns out the UISearchBar
is the delegate for the UITextField
it contains you could swizzle the call to textFieldShouldClear:... Not ideal, clearly, but technically feasible.
从这里,您可以将UITextField委托重新分配给您自己的实现,注意将委托调用转发给旧委托。这样你就可以拦截textFieldShouldClear:。或者如果事实证明UISearchBar是它包含的UITextField的委托,你可以调用textFieldShouldClear:...不理想,但技术上可行。
#2
2
I had the same issue and I solved this issue by using this function.
我有同样的问题,我通过使用此功能解决了这个问题。
- (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];
}];
}
}
#3
1
Here is an answer from a previous question, this should do exactly what you want. UISearchbar clearButton forces the keyboard to appear
以下是上一个问题的答案,这应该完全符合您的要求。 UISearchbar clearButton强制键盘出现
#4
0
Here is "Method Swizzling" solution.
这是“Method Swizzling”解决方案。
- Create a new Category of
UISearchBar
. This category create a new method and swizzle method between-(BOOL)textFieldShouldClear:(UITextField *)textField;
and-(BOOL)jbm_textFieldShouldClear:(UITextField *)textField
in runtime. - Customize a new Protocol of
UISearchBarDelegate
in order to add a new method- (void)searchBarClearButtonClicked:(id)sender;
创建一个新的UISearchBar类别。这个类创建了一个新方法和swizzle方法 - (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
Reference
-
Dave DeLong - How to add a method to an existing protocol in Cocoa?
Dave DeLong - 如何在Cocoa中为现有协议添加方法?
-
Nikolay Vlasov - CCBottomRefreshControl
Nikolay Vlasov - CCBottomRefreshControl
#1
7
The UISearchBar
doesn't have a delegate method for this event. You can nearly get what you want by implementing the textDidChange:
method of the callback delegate and checking for an empty string.
UISearchBar没有此事件的委托方法。通过实现回调委托的textDidChange:方法并检查空字符串,您几乎可以获得所需的内容。
I don't recommend it, but there is another possible way. The UISearchBar
is composed of a UITextField, which does have a delegate method that is called when the user taps the clear button (textFieldShouldClear:
). You can get the UITextField
by traversing the UISearchBar
's child views:
我不推荐它,但还有另一种可能的方法。 UISearchBar由一个UITextField组成,它有一个委托方法,当用户点击clear按钮(textFieldShouldClear :)时会调用该方法。您可以通过遍历UISearchBar的子视图来获取UITextField:
(this is in the context of a derived UISearchBar
class)
(这是在派生的UISearchBar类的上下文中)
- (UIView*) textField
{
for (UIView* v in self.subviews)
{
if ( [v isKindOfClass: [UITextField class]] )
return v;
}
return nil;
}
from here, you could re-assign the UITextField
delegate to your own implementation, taking care to forward delegate calls to the old delegate. This way you could intercept textFieldShouldClear:
. Or if it turns out the UISearchBar
is the delegate for the UITextField
it contains you could swizzle the call to textFieldShouldClear:... Not ideal, clearly, but technically feasible.
从这里,您可以将UITextField委托重新分配给您自己的实现,注意将委托调用转发给旧委托。这样你就可以拦截textFieldShouldClear:。或者如果事实证明UISearchBar是它包含的UITextField的委托,你可以调用textFieldShouldClear:...不理想,但技术上可行。
#2
2
I had the same issue and I solved this issue by using this function.
我有同样的问题,我通过使用此功能解决了这个问题。
- (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];
}];
}
}
#3
1
Here is an answer from a previous question, this should do exactly what you want. UISearchbar clearButton forces the keyboard to appear
以下是上一个问题的答案,这应该完全符合您的要求。 UISearchbar clearButton强制键盘出现
#4
0
Here is "Method Swizzling" solution.
这是“Method Swizzling”解决方案。
- Create a new Category of
UISearchBar
. This category create a new method and swizzle method between-(BOOL)textFieldShouldClear:(UITextField *)textField;
and-(BOOL)jbm_textFieldShouldClear:(UITextField *)textField
in runtime. - Customize a new Protocol of
UISearchBarDelegate
in order to add a new method- (void)searchBarClearButtonClicked:(id)sender;
创建一个新的UISearchBar类别。这个类创建了一个新方法和swizzle方法 - (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
Reference
-
Dave DeLong - How to add a method to an existing protocol in Cocoa?
Dave DeLong - 如何在Cocoa中为现有协议添加方法?
-
Nikolay Vlasov - CCBottomRefreshControl
Nikolay Vlasov - CCBottomRefreshControl