失去焦点时隐藏UISearchBar键盘

16

我不确定为什么这样很难。我在页面顶部有一个UISearchBar。当用户在该UISearchBar中键入时,它将自动过滤下面的UITableView中的结果。由于按键时已搜索,因此不需要搜索按钮。

应用程序的流程是,用户在搜索栏中键入搜索(显示键盘),然后将在表视图中滚动结果 - 此时需要消除键盘。

我很难使键盘消失。

我知道我需要执行:

    [searchBar resignFirstResponder];

我想让键盘在用户触摸表视图时立即消失,但我找不到需要在哪个delegate上执行此操作。有任何想法吗?


请查看此链接:https://dev59.com/GFvUa4cB1Zd3GeqPtnE5 - 0xKayvan
7个回答

10

试试这个:

- (void)viewWillDisappear:(BOOL)animated {

    [super viewWillDisappear:animated];

    [searchBar resignFirstResponder];

}

对我很有效


2
我认为最简单(也是最好的)方法是对全局视图进行子类化,并使用hitTest:withEvent方法来监听任何触摸。键盘上的触摸不会被注册,因此只有在您触摸/滚动/轻扫/捏等其他位置时才会调用hitTest:withEvent,然后调用[self endEditing:YES]。
这比使用touchesBegan更好,因为如果您点击视图顶部的按钮,则不会调用touchesBegan。它也比使用暗屏幕更好,因为在复杂和动态的用户界面中,您无法在每个地方都放置暗屏幕。而且,它比调用[searchBar resignFirstResponder]更好,因为您可能在屏幕上有许多文本字段,所以这适用于所有文本字段。

1
由于结果将以表格视图的形式呈现,因此使用UIScrollView的委托(UITableView响应)方法- (void)scrollViewDidScroll:(UIScrollView *)scrollView

您需要使您的视图控制器响应UITableView的数据源和委托(在.h文件中):

<UITableViewDataSource, UITableViewDelegate>

然后在您的初始化方法中的.m文件中添加:

self.tableView.dataSource = self;
self.tableView.delegate = self;

最后,添加这个方法:
- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
    [self.view endEditing:YES];
}

这将使得 UISearchBar 失去焦点,键盘也会隐藏。

1
一种可能是UISearchBar属于一个控制器,该控制器显示在UIModalPresentationFormSheet中。 我遇到了同样的问题,并发现这与UIViewController的“disablesAutomaticKeyboardDismissal”方法有关。 Apple文档中如下所述:
覆盖此方法的子类,以允许或禁止在从需要输入视图的控件更改到不需要输入视图的控件时解除当前输入视图(通常是系统键盘)。在正常情况下,当用户点击需要输入视图的控件时,系统会自动显示该视图。在不需要输入视图的控件中点击后,当前输入视图将被解除,但并非所有情况都是如此。您可以在这些未解决的情况下重写此方法,以允许输入视图被解除,或使用此方法来防止在其他情况下解除视图。

此方法的默认实现在视图控制器的模态呈现样式设置为UIModalPresentationFormSheet时返回YES,并对其他呈现样式返回NO。因此,系统通常不允许在模态表单中解除键盘。

在我的情况下,我在导航栏中显示了搜索栏,因此必须创建一个UINavigationViewController的子类来覆盖此方法:

- (BOOL)disablesAutomaticKeyboardDismissal {
    return NO;
}

接下来,调用resignFirstResponder将最终使键盘消失。


1
你可能想像Cydia(越狱包装UI)一样实现它 - 有一个搜索按钮,当你按下搜索按钮时,它会关闭键盘。结果仍然会根据你的输入进行过滤以进行预览。

1
这将需要按下搜索按钮以移除键盘 - 我觉得这一步骤应该是不必要的,可能会让用户感到沮丧。谢谢。 - rein

0
可能回答晚了,但这对未来的任何人可能有所帮助。这段特定的代码对我很有效。附言:我不是这个解决方案的所有者,之前在网上找到的。
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
UITouch *touch = [[event allTouches] anyObject];
if ([self.srchBar isFirstResponder] && [touch view] != self.srchBar)
{
    [self.srchBar resignFirstResponder];
}   
[super touchesBegan:touches withEvent:event];
}

0

给定一个带有 searchBar 变量的视图,请将此方法添加到视图中:

override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView?
{
    if searchBar.isFirstResponder && !searchBar.point(inside: point, with: event){
        searchBar.resignFirstResponder()
    }
    return super.hitTest(point, with: event)
}

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