成为第一响应者在视图中工作DidAppear,但在viewDidLoad中不起作用



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

我可以确保viewDidAppearviewDidLoad都被调用了。

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

(我使用的是StoryBoard)

按照答案,我试图把代码在viewWillLoad,但仍然没有工作。(在viewWillLoad, self.searchBar.window为nil)

可能在viewDidLoad中不起作用,因为视图还没有添加到视图层次结构中。但是根据apple文档,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
    });
 }

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

你应该调用viewDidLayoutSubviews(),下面的代码只在第一次视图布局子视图时设置textField成为firstresponder,它应该是。

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

所有IBOutlet对象都是在viewDidLoad中加载的,如果你在viewDidLoad中调用方法那么动作就不会执行因为在对象被加载之前我们什么都做不了所以最好把代码写在

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

这将有助于:

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

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

viewDidAppear/viewDidLoad改为viewWillAppear

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

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

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

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

最新更新