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

Xha*_*Liu 15 iphone xcode objective-c uisearchbar ios

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

我可以保证双方viewDidAppearviewDidLoad已调用.

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

(我正在使用StoryBoard)

按照答案,我试着把代码放进去viewWillLoad,但仍然无法正常工作.(在viewWillLoad,self.searchBar.window是零)

小智 6

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

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


Mik*_*ail 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.
Run Code Online (Sandbox Code Playgroud)

因此,我认为,实现必要行为的最佳位置是将call调用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
    });
 }
Run Code Online (Sandbox Code Playgroud)

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


iPa*_*tel 1

viewWillAppear代替viewDidAppear/viewDidLoad.

因为viewWillAppear方法调用的时候会出现View(进程中),更多信息viewWillAppear阅读这个官方文档。

- (void)viewWillAppear:(BOOL)animated
{
    [self.searchBar becomeFirstResponder];
    [super viewWillAppear:animated];
}
Run Code Online (Sandbox Code Playgroud)