オンラインで検索し、この問題について他の開発者と話をするのにかなりの時間を費やしました。正確な問題は、このSO post( ISearchBarに焦点を当てるがキーボードは表示されない )で説明されていますが、それは何年も前のものです。
私は最近、IBで非推奨のUISearchDisplayControllerとUISearchBarを使用することから切り替え、iOS8のコードを介してUISearchControllerに切り替えました。
しかし、私が得ている問題は、フォーカスが正しく割り当てられていることです(ビューが読み込まれた後、キャンセルボタンが検索バーの右側にアニメーションするためわかります)が、キーボードは表示されません。
これが私が持っているコードです。
.h
@property (nonatomic, strong) UISearchController *searchController;
.m
- (void)viewDidLoad {
[super viewDidLoad];
...
[self initializeSearchController];
....
}
- (void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
[self.searchController setActive:YES];
[self.searchController.searchBar becomeFirstResponder];
}
- (void)initializeSearchController {
self.searchController = [[UISearchController alloc] initWithSearchResultsController:nil];
self.searchController.searchResultsUpdater = self;
self.searchController.dimsBackgroundDuringPresentation = NO;
self.searchController.delegate = self;
self.searchController.searchBar.delegate = self;
[self.searchController.searchBar sizeToFit];
[self.tableView setTableHeaderView:self.searchController.searchBar];
self.definesPresentationContext = YES;
}
私が今までに試したこと。
別のSO投稿で示唆されているように、0.2秒の遅延でbecomeFirstResponderを呼び出してみました。
ViewDidAppearにブレークポイントを設定し、self.searchControllerとself.searchController.searchBarの両方が有効なオブジェクトであり、どちらもnilでないことを確認しました。
UISearchControllerDelegateに準拠し、次のコードスニペットを使用してみました
ここに:
- (void)didPresentSearchController:(UISearchController *)searchController {
//no matter what code I put in here to becomeFirstResponder, it doesn't
//matter because this is never called, despite setting the
//self.searchController.delegate = self AND
//self.searchController.searchBar.delegate = self.
}
ストーリーボードでゼロから新しいビューを作成し、代わりにそのビューに切り替えて、ビューに古いsearchBarレムナントがないようにしました。これも機能しませんでした。
これは実際のデバイス(iPhone 6)でしかテストしていませんが、キーボードが表示されないというシミュレーターの問題ではありません。
私はアイデアが尽きており、これに関するすべての質問と回答をウェブで見ました。何も機能していません。
何が起こっているのかを再度明確にするために、searchBarは正しく最初のレスポンダーになり、その右側のキャンセルボタンが画面上にアニメーションを表示しますが、キーボードは表示されず、searchBarでカーソルは点滅しません。
コードは問題ないようです。あなたが説明していることは正常な行動ではありません。最初にできることは、UISearchController
機能だけを使用して新しいプロジェクトを作成し、それがどうなるかを確認することです。質問を編集して、見やすくすることができます。
UISearchController
の実装方法の良い例がここにあります: Sample-UISearchController
追加:
-(void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
[self.searchController.searchBar becomeFirstResponder];
}
MasterViewController_TableResults.m
期待どおりの結果が得られ、iOS 8.3を搭載したiPadおよびiPhoneでの起動時にキーボードがポップアップ表示されました。
そのプロジェクトに目を通し、あなたが何を違うやり方でしたかを見ることができます。
編集:
[self.searchController setActive:YES]
は、becomeFirstResponder
の前に呼び出され、キーボードは表示されません。それがバグなのかどうかな。
同じ迷惑な問題がありました。 SearchControllerをアクティブに設定すると、検索コントローラーとキーボードの両方が表示されると思います。残念ながら、最初の部分のみを行います。
私の解決策
viewDidAppearで、検索コントローラーをアクティブにします。
override func viewDidAppear(animated: Bool) {
super.viewDidAppear(animated)
resultSearchController.active = true
}
アクティブになると、didPresentSearchControllerで最初のレスポンダーとしてmake
func didPresentSearchController(searchController: UISearchController) {
searchController.searchBar.becomeFirstResponder()
}
Swift 3.0(iOS 10)ワーキングソリューション:
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
searchController.isActive = true
DispatchQueue.main.async { [unowned self] in
self.searchController.searchBar.becomeFirstResponder()
}
}
IOS 9では、becomeFirstResponder()
を次の実行ループまで遅らせるのに十分であることがわかりました。
func focusSearchField() {
searchController?.active = true
// skipping to the next run loop is required, otherwise the keyboard does not appear
dispatch_async(dispatch_get_main_queue(), { [weak self] in
self?.searchController?.searchBar.becomeFirstResponder()
})
}
IOS 10では、メインスレッドのデリゲートメソッドでコードを実行する必要がありました。まず、viewDidAppearでアクティブをYESに設定し、
-(void)viewDidAppear:(BOOL)animated{
[super viewDidAppear:animated];
[self.searchController setActive:YES];
}
そしてデリゲートメソッドで:
- (void)didPresentSearchController:(UISearchController *)searchController
{
dispatch_async(dispatch_get_main_queue(), ^{
[searchController.searchBar becomeFirstResponder];
});
}
ワーキングソリューション:-
BeginFirstResponderの前に[self.searchController setActive:YES]を使用しないでください。
- (void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
dispatch_async(dispatch_get_global_queue(0, 0), ^{
dispatch_async(dispatch_get_main_queue(), ^{
// [self.searchController setActive:YES];
[self.searchController.searchBar becomeFirstResponder];
});
});
}
動作するソリューションは次のとおりです。
1. ViewDidLayoutSubviews
を表示しているView ControllerでUISearchController
をオーバーライドします
2. ViewDidLayoutSubviews
をオーバーライドし、その内部で検索バーを最初にレスポンダーにします。
IOS> 9.0でテスト済み
注意:次のようにファーストレスポンダーにする前にヌルチェックを入れてください
if((searchController != null)&&(searchController.SearchBar != null))
searchController.SearchBar.BecomeFirstResponder();
これは、キャンセルボタンが押されたときにViewDidLayoutSubviews
も呼び出されるためです。
これはXamarinでうまくいきました。
-(void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
[self.searchController setActive:YES];
}
//and then in the delegate method:
- (void)didPresentSearchController:(UISearchController *)searchController
{
dispatch_async(dispatch_get_main_queue(), ^{
[searchController.searchBar becomeFirstResponder];
});
}
//The above works for me in addition to this I had to add:
-(void)viewWillDisappear:(BOOL)animated {
[searchController setActive:NO];
}
UISearchBarでキーボードが表示されないという問題がありました
[searchBar becomeFirstResponder];
ネットで検索することで、これを見つけました thread Apple keyWindow。
私が取り組んでいるアプリケーションは次のようなことをします:
しなければならなかった
[[[[UIApplication sharedApplication] windows] firstObject] makeKeyWindow];
ウィンドウBの辞任後、キーボードの問題はもうありません。
これは、シミュレーター設定にも関連している可能性があります。 [ハードウェア]-> [キーボード]-> [ハードウェアキーボードの接続]を無効にします。