15

我的应用程序有一个模式视图控制器,包括一个搜索栏。当视图出现时,我希望搜索栏成为焦点。我试过[self.searchBar becomeFirstResponder]viewDidLoad,但它没有用。后来我把它放进去viewDidAppear,它工作。但是使用这种解决方法,会出现明显的延迟。(视图完全出现后,键盘开始出现)

我可以确保两者viewDidAppearviewDidLoad被调用。

如果我希望搜索栏在视图出现时立即获得焦点,我应该怎么做?

(我正在使用故事板)

按照答案,我尝试将代码放入viewWillLoad,但仍然无法正常工作。(在viewWillLoad,self.searchBar.window为零)

4

7 回答 7

6

可能它在 viewDidLoad 中不起作用,因为视图尚未添加到视图层次结构中。但根据苹果文档 becomeFirstResponder 应该只在附加到 UIWindow 的对象上调用:

However, you should only call it on that view if it is part of a view hierarchy. 
If the view’s window property holds a UIWindow object, it has been installed 
in a view hierarchy; if it returns nil, the view is detached from any hierarchy.

所以,我认为,实现必要行为的最佳位置是将调用放入viewWillAppear方法中。

更新。

因此,在 viewWillAppear 控制器的视图中尚未附加到 UIWindow ...它只会通知,该视图将被添加到视图层次结构中

这可能有些棘手,但您可以在 viewWillAppear 中做一些小的延迟:

 - (void)viewWillAppear:(BOOL)animated {
    [super viewWillAppear:animated];
    double delayInSeconds = 0.05;
    dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(delayInSeconds * NSEC_PER_SEC));
    dispatch_after(popTime, dispatch_get_main_queue(), ^{ 
        make first responder here
    });
 }

但我相信应该有更好的解决方案

于 2013-03-18T09:03:42.630 回答
6

您应该在 viewDidLayoutSubviews() 中调用,下面的代码设置 textField becomeFirstResponder 仅在第一次查看布局子视图时,它应该是。

var isFirstLayout: Bool = true
override func viewDidLayoutSubviews() {
    super.viewDidLayoutSubviews()
    if isFirstLayout {
        defer { isFirstLayout = false }
        textField.becomeFirstResponder()
    }
}
于 2018-07-19T15:51:43.477 回答
4

所有 IBOutlet 对象都加载到 viewDidLoad 中,如果您在 viewDidLoad 中调用该方法,则该操作不会执行,因为在加载对象之前我们无法做任何事情,这就是为什么最好在其中编写代码

-(void)viewWillAppear:(BOOL)animated{
//write here
} 

然后它工作正常。

于 2013-03-18T09:00:52.643 回答
3

这将有助于:

- (void)viewWillAppear:(BOOL)animated {
    [super viewWillAppear:animated];
    dispatch_async(dispatch_get_main_queue(), ^{
        [self.quantifyTextField becomeFirstResponder];
    });
}
于 2014-03-25T22:45:12.670 回答
2

应该在所有 UIViewController 动画之后完成文本字段/视图的第一响应者,这发生在加载和呈现视图时。所以最好的地方是viewDidAppear。

于 2013-03-18T10:42:16.677 回答
1

viewWillAppear代替viewDidAppear/viewDidLoad

因为viewWillAppear方法是在 View 的时候调用才会出现(in process),更多信息viewWillAppear阅读这个官方文档。

- (void)viewWillAppear:(BOOL)animated
{
    [self.searchBar becomeFirstResponder];
    [super viewWillAppear:animated];
}
于 2013-03-18T08:59:59.863 回答
1

我知道这是一个有点旧的线程,但我认为它可以帮助在添加此代码时遇到键盘问题的人。

请记住在 viewWillDisappear 中将 textfield 委托设置为 nil,否则如果您在不关闭键盘的情况下弹出/关闭视图控制器,则键盘将不会再次显示。

于 2016-08-17T02:47:18.960 回答