becomeFirstResponder在viewDidAppear中工作,但在viewDidLoad中不起作用

时间:2013-03-18 08:54:37

标签: iphone ios objective-c xcode uisearchbar

我的应用程序有一个模态视图控制器,包括一个搜索栏。当视图出现时,我希望搜索栏能够被聚焦。我在[self.searchBar becomeFirstResponder]中尝试了viewDidLoad,但它没有用。后来我把它放在viewDidAppear中,它起作用了。但是通过这种解决方法,存在明显的延迟。 (视图完全出现后,键盘开始出现)

我可以确保已调用viewDidAppearviewDidLoad

如果我想让搜索栏立即聚焦并显示视图,我该怎么办?

(我正在使用StoryBoard)

按照答案,我尝试将代码放在viewWillLoad中,但仍然无效。 (在viewWillLoad中,self.searchBar.window为零)

7 个答案:

答案 0 :(得分:5)

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

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
    });
 }

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

答案 1 :(得分:4)

所有IBOutlet对象都在viewDidLoad中加载,如果你在viewDidLoad中调用该方法,那么该动作没有执行,因为在加载对象之前我们无法做任何事情,这就是为什么更好地编写代码

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

然后它运作正常。

答案 2 :(得分:4)

您应该在viewDidLayoutSubviews()中调用,下面的代码仅在第一次设置视图布局子视图时才将textField设置为FirstResponder。

var isFirstLayout: Bool = true
override func viewDidLayoutSubviews() {
    super.viewDidLayoutSubviews()
    if isFirstLayout {
        defer { isFirstLayout = false }
        textField.becomeFirstResponder()
    }
}

答案 3 :(得分:3)

这会有所帮助:

- (void)viewWillAppear:(BOOL)animated {
    [super viewWillAppear:animated];
    dispatch_async(dispatch_get_main_queue(), ^{
        [self.quantifyTextField becomeFirstResponder];
    });
}

答案 4 :(得分:2)

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

答案 5 :(得分:1)

viewWillAppear而不是viewDidAppear/viewDidLoad

因为在查看时会调用viewWillAppear方法(正在处理),有关详细信息about viewWillAppear read this official Document.

- (void)viewWillAppear:(BOOL)animated
{
    [self.searchBar becomeFirstResponder];
    [super viewWillAppear:animated];
}

答案 6 :(得分:1)

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

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