当您点击搜索文本框下方和键盘上方时,是否有人知道如何从UISearchBar中取消(退出First Responder)?任何人都可以帮助张贴一些代码来处理这个?当用户点击视图时取消UISearchBar
谢谢
当您点击搜索文本框下方和键盘上方时,是否有人知道如何从UISearchBar中取消(退出First Responder)?任何人都可以帮助张贴一些代码来处理这个?当用户点击视图时取消UISearchBar
谢谢
我从iphonedevbook(样本代码项目04)得到的另一个想法是使用一个大的透明按钮,它位于所有其他控件后面,除了点击所有其他控件之外什么也不做,只是退出所有第一响应者。即如果用户点击没有更重要的控件的地方 - 这是直观的行为 - 搜索栏和键盘消失。
首先,您需要对搜索栏的引用。假设您的控制器对象具有对象引用UISearchBar * theSearchBar,并且您在创建UISearchBar对象时分配它。
接下来,您需要检测是否触摸了包含视图。被触摸的视图“知道”,但您需要将该信息提供给控制器。可悲的是,苹果公司并没有提供一个简单的方法来做到这一点,但也不是那么难。
我的解决方案是用一个UIControl替换UIViewController对象通常创建的标准UIView,然后使UIViewController响应触摸事件。
MainController.m
- (void) loadView {
UIControl *control = [[UIControl alloc] initWithFrame: <desired frame>];
[control addTarget: self action: @selector(touchUpInside)
forControlEvents: UIControlEventTouchUpInside];
// or touch down events, or whatever you like
self.view = control;
[control release];
}
- (void) viewDidLoad {
[super viewDidLoad];
theSearchBar = [[UISearchBar alloc] initWithFrame: <desired frame>];
// insert code to finish customizing the search bar
[self.view addSubview: theSearchBar];
}
- (void) touchUpInside {
if [theSearchBar isFirstResponder] {
// grab any data you need from the search bar
[theSearchBar resignFirstResponder];
}
}
MainController.h
@interface MainController : UIViewController
{
UISearchBar *theSearchBar;
}
澄清:
只有一个单一的对象 - 我们称之为类MainController - 这是UIViewController的子类。上面列出的所有方法都在MainController中实现。 theSearchBar在.h文件中声明为UISearchBar *。
您是使用Interface Builder定义视图和控制器吗?如果是这样,我建议你学会如何不使用它 - 一旦你进入我们在这里讨论的那种技巧,它变得更加困难而不是帮助 - 我根本不使用它。
如何从touchUpInside事件获取对searchBar的引用?我在包含搜索栏的viewcontroller类中有touchUpInside。 – 2009-08-17 16:53:00
你的意思是,为了调用resignFirstResponder?如果您在创建时将其作为参考保存,您已经拥有它。 – Amagrammer 2009-08-17 17:54:59
我有点困惑。上面的代码应该与我创建搜索栏的代码位于不同的视图控制器中吗?另外为什么你在你的loadView例程中创建一个UIControl而不是UISearchBar? – 2009-08-17 18:08:41
我做到了这一点通过使用UITapGestureRecognizer:
UIGestureRecognizer* cancelGesture;
- (void) backgroundTouched:(id)sender {
[self.view endEditing:YES];
}
#pragma mark - UISearchBarDelegate
-(void)searchBarTextDidBeginEditing:(UISearchBar *)searchBar {
cancelGesture = [UITapGestureRecognizer new];
[cancelGesture addTarget:self action:@selector(backgroundTouched:)];
[self.view addGestureRecognizer:cancelGesture];
}
-(void)searchBarTextDidEndEditing:(UISearchBar *)searchBar {
if (cancelGesture) {
[self.view removeGestureRecognizer:cancelGesture];
[cancelGesture release];
cancelGesture = nil;
}
}
的代码是一个光秃秃的,但你可以看到的意图。当SearchBar开始编辑时,您将一个轻击手势识别器附加到视图控制器的视图中,并在停止编辑时将其删除。
你可以解决一些问题:如果你点击除键盘或搜索栏的文本字段以外的任何东西,识别器将捕获点击 - 所以如果你使用清除,取消,范围或结果按钮,他们将不会正确响应。
在我的特殊场景中,我有一个覆盖视图的暴露区域的UITableView,因此我附加了手势识别器而不是视图控制器主视图,从而隔离手势将响应的区域。
我最终使用了Hauke's和Beau Scott的方法。我遇到了两个使用他们的解决方案的问题:
1)如果屏幕上还有其他东西,点击它不会导致resignFirstResponder被调用。例如,如果用户点击按钮而不是按钮周围的空间,则该按钮将吃掉该事件。然而,Beau Scott的解决方案解决了这个问题。
2)点击搜索栏本身会导致resignFirstResponder被调用。显然,当你点击UISearchBar时,你不希望键盘消失。下面描述的一个小改变解决了这个问题
我最终建立了我的观点如下。父视图有两个子项--UISearchBar和一个子视图,它包含我的其他UI元素。子视图占用UISearchBar下面的整个屏幕。然后我用博·斯科特的确切的代码添加和删除手势识别,而不是增加它self.view我把它添加到子视图:
IBOutlet UIView *gestureRecognizer;
...
-(void)searchBarTextDidBeginEditing:(UISearchBar *)searchBar {
cancelGesture = [UITapGestureRecognizer new];
[cancelGesture addTarget:self action:@selector(backgroundTouch:)];
[gestureRecognizer addGestureRecognizer:cancelGesture];
}
-(void)searchBarTextDidEndEditing:(UISearchBar *)searchBar {
if (cancelGesture) {
[gestureRecognizer removeGestureRecognizer:cancelGesture];
[cancelGesture release];
cancelGesture = nil;
}
}
添加在父视图中双击手势(在的UISearchBar的)
[self addGestureRecognizer:[[UITapGestureRecognizer alloc] initWithTarget:searchBar action:@selector(resignFirstResponder)]];
如果'self''是一个'''UIView''',这段代码是有意义的。但大多数情况下'''self'''实际上是一个'''UIViewController''',所以这应该是'''[self.view addGestureRecognizer:[[UITapGestureRecognizer alloc] initWithTarget:self.searchBar action: @selector(resignFirstResponder)]];''' – mikeho 2016-03-06 05:34:27
@Gia党的答案是简单的,但我不子类UIView
,只有UIViewController
,所以我的CAL l是略有不同。另外,由于我不知道实际拨打resignFirstResponder
的开销,我宁愿先检查。这是更多的代码,但由于所有这些都是在主线程上完成的(这可能会减慢UI),所以我宁愿先检查一下。
@implementation MyController : UIViewController {
@private
UISearchController *_uiSearchController;
}
- (void)viewDidLoad {
// add tap on view to resign the responder if we're in the middle of typing in the search
UITapGestureRecognizer *tapGestureRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(closeKeyboardIfNeeded)];
[self.view addGestureRecognizer:tapGestureRecognizer];
}
- (void)closeKeyboardIfNeeded {
if (![_uiSearchController.searchBar isFirstResponder]) {
return;
}
[_uiSearchController.searchBar resignFirstResponder];
}
@end
至于其他答案,要小心不断重新创建对象。无论是创建本身还是通过ARC垃圾收集,性能总会受到影响,并且这些事情会降低主线程速度。根据您在主线程中所做的操作,它可能会对性能产生重大影响。
这与我上面的建议实际上是一样的。实施起来可能会更简单一些。 – Amagrammer 2009-08-18 13:40:09
谢谢豪克!创建透明按钮并处理touchup事件以辞退第一个响应者的技巧。 – 2009-08-18 15:21:47
我现在有一个其他问题是让我们说我有一个包含该透明按钮后面的mkmapview的视图。一旦searchBar消失,我怎样才能重新激活地图? – 2009-08-18 15:28:05