簡體   English   中英

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

[英]becomeFirstResponder works in viewDidAppear but doesn't work in viewDidLoad

我的應用程序有一個模態視圖控制器,包括一個搜索欄。 當視圖出現時,我希望搜索欄能夠被聚焦。 我在viewDidLoad嘗試了[self.searchBar becomeFirstResponder] ,但它沒有用。 后來我把它放在viewDidAppear ,它起作用了。 但是通過這種解決方法,存在明顯的延遲。 (視圖完全出現后,鍵盤開始出現)

我可以確保已調用viewDidAppearviewDidLoad

如果我希望搜索欄能夠立即聚焦並顯示視圖,我該怎么辦?

(我正在使用StoryBoard)

按照答案,我試圖將代碼放在viewWillLoad ,但仍然無法正常工作。 (在viewWillLoadself.searchBar.window為nil)

可能它在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
    });
 }

但我相信應該有更好的解決方案

你應該在viewDidLayoutSubviews()中調用,下面的代碼只在第一次查看布局子視圖時設置textField,成為FirstFirstResponder,它應該是。

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。

viewWillAppear的instad viewDidAppear/viewDidLoad

因為viewWillAppear方法在View出現時會調用( 正在進行中 ), 有關viewWillAppear更多信息,請閱讀此官方文檔。

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

我知道它有點舊線程,但我認為它可以幫助那些在添加此代碼時遇到鍵盤問題的人。

請記住在viewWillDisappear中將textfield委托設置為nil,否則如果在不關閉鍵盤的情況下彈出/關閉視圖控制器,鍵盤將不會再次顯示。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM