Table of Contents
<a id="1"></a>背景
當我們使用 UISearchBar
時费坊,常常會想當 searchBar
出現(xiàn)時兑凿,自動獲得焦點并喚起鍵盤缸榄,這樣就能省去用戶手動點擊搜索框準備輸入這個步驟姥饰。
從 Apple 的官方文檔中恩脂,我們知道:
- becomeFirstResponder
Notifies the receiver that it is about to become first responder in its window.
即對于繼承自 UIResponder
的類钳榨,如:UISearchBar
狂芋,使用 becomeFirstResponder
能夠使其獲得焦點州藕,同時 CocoaTouch
還做了優(yōu)化:獲得焦點后當控件需要輸入時束世,能夠自動喚起鍵盤。
因此床玻,我們只需要關(guān)注如何使 UISearchBar
獲得焦點毁涉。但是某些情況下,使用 becomeFirstResponder
并不能實現(xiàn)我們的目標锈死。下面我們將在實例中解決這個問題贫堰。
<a id="2"></a>問題描述
在目前我正在開發(fā)的天氣APP(源碼請看這里)中穆壕,主界面的左側(cè)有一個 tableView
用于顯示不同的城市,其中有一個 tableViewCell
其屏,當點擊它的時候喇勋,會出現(xiàn)另一個 viewController
供用戶添加新的城市。
假設(shè)這個 viewController
為 viewController_A
偎行,這個類里包含了一個 tableView川背,和一個 UISearchBarController
。
這樣把 tableView
的 tableHeaderView
設(shè)置為 searchController.searchBar
蛤袒,就能把 searchBar
顯示在 tableView 上熄云。
現(xiàn)在的問題就是,當點擊 tableViewCell
妙真,出現(xiàn)了包含 searchBar
的 viewController_A
時缴允,并不會將焦點定位到 searchBar
上,當然也不會出現(xiàn)鍵盤隐孽。
我嘗試了在 viewController_A
的 viewDidLoad()
里用:
searchController.active = true
searchController.searchBar.becomeFirstResponder()
第一行用于激活 searchController
癌椿,第二行讓 searchBar
獲得焦點。
但是運行結(jié)果表明菱阵,只激活了 searchController
踢俄,而沒有把焦點定位到 searchBar
上。
<a id="3"></a>原因分析
在官方文檔里有如下描述:
A responder object only becomes the first responder if the current responder can resign first-responder status (canResignFirstResponder) and the new responder can become first responder.
一個 responder
想要成功獲得焦點晴及,必需滿足都办,上一個 responder
能夠放棄焦點,并且當前的 responder
能夠獲得焦點虑稼。
因此琳钉,問題就出在之前描述的那種情況下,使用:SearchController.searchBar.becomeFirstResponder()
的時候蛛倦,searchBar
并沒有能力獲得焦點歌懒,因此焦點設(shè)置不成功。
但是為什么 searchBar
這時候沒有能力獲得焦點呢溯壶?
因為及皂,在 viewDidLoad()
的時候,searchController
也剛剛初始化且改,必需得等到 searchController
初始化完畢验烧,呈現(xiàn)出來的時候,才能為 searchBar
設(shè)置焦點又跛。
<a id="4"></a>解決方法
為了在 searchController
初始化之后碍拆,再進行 searchBar
焦點設(shè)置,我們可以為 viewController_A
聲明 UISearchControllerDelegate
,并在 didPresentSearchController
中添加焦點設(shè)置代碼感混,如下:
extension ViewController_A : UISearchControllerDelegate {
func didPresentSearchController(searchController: UISearchController) {
searchController.searchBar.becomeFirstResponder()
}
}
這樣就能在出現(xiàn) viewController_A
后端幼,自動將焦點定位到 searchBar
并喚起鍵盤。
<a id="5"></a>結(jié)語
這其實是 View
和 ViewController
的生命周期(cycle)的問題浩习,在周期的各個階段静暂,會觸發(fā)相應(yīng)的事件济丘,可以進行相應(yīng)的設(shè)置谱秽。
之前在 viewDidLoad()
中同時設(shè)置 searchController.active
和 searchController.searchBar.becomeFirstResponder()
,由于此時 searchBar
是不可用的摹迷,因此對它的設(shè)置無效疟赊。必需在 searchController
初始化完畢才能對 searchBar
進行設(shè)置。因此峡碉,后來近哟,我們在 didPresentSearchController
中設(shè)置 searchBar
,就能設(shè)置成功了鲫寄。
附上我的Github:LinShiwei (Lin Shiwei) · GitHub