xcode becomeFirstResponder 在 vi​​ewDidAppear 中工作,但在 viewDidLoad 中不起作用

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/15472784/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-15 03:00:15  来源:igfitidea点击:

becomeFirstResponder works in viewDidAppear but doesn't work in viewDidLoad

iphoneiosobjective-cxcodeuisearchbar

提问by Xhacker Liu

My Application has a modal view controller, including a search bar. When the view comes up, I want the search bar to be focused. I tried [self.searchBar becomeFirstResponder]in viewDidLoad, but it didn't work. Later on I put it in viewDidAppear, it worked. But with this workaround, there is a visible delay. (after the view fully appeared, the keyboard began to appear)

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

I can ensure both viewDidAppearand viewDidLoadhave been invoked.

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

What should I do if I want the search bar to be focused instantly with the view appear?

如果我希望搜索栏在视图出现时立即聚焦,我该怎么办?

(I'm using StoryBoard)

(我正在使用故事板)

Followed the answers, I tried to put the code in viewWillLoad, but still didn't work. (in viewWillLoad, self.searchBar.windowis nil)

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

回答by imbaggaarm

You should call in viewDidLayoutSubviews(), the code below set textField becomeFirstResponder only at the first time view layout subviews, and it should be.

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

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

回答by Mikhail

Possibly it does not work in viewDidLoad, as view does not added into view hierarchy yet. But according to apple documentation becomeFirstResponder should be called only on objects attached to UIWindow:

可能它在 viewDidLoad 中不起作用,因为视图尚未添加到视图层次结构中。但根据苹果文档,仅应在附加到 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.

So, i assume, the best place to achieve necessary behavior is to place call into viewWillAppearmethod.

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

Update.

更新。

So, in viewWillAppear controller's view not yet attached to UIWindow... it only notify, that view will be added to view hierarchy

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

It may be some tricky, but you can make some small delay in viewWillAppear:

这可能有些棘手,但您可以在 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
    });
 }

But I believe there is should be a better solution

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

回答by Balu

all the IBOutlet objects are loaded in viewDidLoad,if you are calling the method in viewDidLoad then that action not performed because before the objects are loaded we can't do anything that's whybetter to write that code in

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

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

then it works fine.

然后它工作正常。

回答by Vitaliy Gozhenko

This will help:

这将有助于:

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

回答by Jeepston

Making text field/view first responder should be done after all UIViewController animations, which take place when view is loaded and presented. So the best place is viewDidAppear.

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

回答by iPatel

Write viewWillAppearinstad of viewDidAppear/viewDidLoad.

viewWillAppearviewDidAppear/viewDidLoad.

BecauseviewWillAppearmethod is call at the time of View will appear (in process), for more information about viewWillAppearread this official Document.

因为viewWillAppear方法是在搜索的时候会出现(呼叫过程),以获取更多信息有关viewWillAppear阅读本正式文件。

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

回答by Lucas Pang

I know it is a bit old thread, but I think it can help someone that is facing some keyboard issue when adding this code.

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

Remember to set the textfield delegate to nil in viewWillDisappear, otherwise the keyboard will not be shown again if you pop/dismiss the view controller without closing the keyboard.

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