ユーザーがUISearchDisplayController
の検索バーの編集を開始するたびに、検索コントローラーがアクティブになり、検索テーブルビューの表示中にビューのナビゲーションバーを非表示にします。 UISearchDisplayController
が再実装せずにナビゲーションバーを非表示にしないようにすることは可能ですか?
IOS 8で導入された新しいUISearchController
クラスにはhidesNavigationBarDuringPresentation
プロパティがあり、ナビゲーションバーを表示したままにする場合はfalseに設定できます(デフォルトでは非表示のままです)。
UISearchDisplayControllerを少しデバッグしたところ、UINavigationControllerのプライベートメソッドを呼び出してナビゲーションバーを非表示にしていることがわかりました。これは-setActive:animated:で発生します。 UISearchDisplayControllerをサブクラス化し、このメソッドを次のコードで上書きする場合、navigationBarが既に非表示になっているように見せかけることで、navigationBarが非表示になるのを防ぐことができます。
- (void)setActive:(BOOL)visible animated:(BOOL)animated;
{
if(self.active == visible) return;
[self.searchContentsController.navigationController setNavigationBarHidden:YES animated:NO];
[super setActive:visible animated:animated];
[self.searchContentsController.navigationController setNavigationBarHidden:NO animated:NO];
if (visible) {
[self.searchBar becomeFirstResponder];
} else {
[self.searchBar resignFirstResponder];
}
}
これがあなたのために働くかどうか私に知らせてください。また、これが将来のiOSバージョンで壊れないことを願っています... iOS 4.0でのみテスト済み。
最も単純なソリューションであり、ハッキングはありません。
@interface MySearchDisplayController : UISearchDisplayController
@end
@implementation MySearchDisplayController
- (void)setActive:(BOOL)visible animated:(BOOL)animated
{
[super setActive: visible animated: animated];
[self.searchContentsController.navigationController setNavigationBarHidden: NO animated: NO];
}
@end
上記の答えは、私にはまったくうまくいきませんでした。私の解決策は、UISearchDisplayControllerをだまして、UINavigationControllerが存在しないと考えるようにすることです。
View Controllerで、このメソッドを追加します
- (UINavigationController *)navigationController {
return nil;
}
本当に悪い考えのように思えたが、これは私にとって厄介な副作用はなかった... Navigation Controllerにアクセスする必要がある場合は、[super navigationController]
。
IOS 8.0以降では、UISearchController
のself.searchController.hidesNavigationBarDuringPresentation
プロパティをfalseにします。
Swift=のコードは次のようになります。
searchController.hidesNavigationBarDuringPresentation = false
UISearchDisplayControllerをサブクラス化せずに、これを別の方法で試しました。 UISearchDisplayControllerのデリゲートを設定したUIViewControllerクラスで、searchDisplayControllerDidBeginSearch:を実装し、使用を追加します
[self.navigationController setNavigationBarHidden:NO animated:YES];
私のためにトリックをしました、それが役立つことを願っています。
わずかに異なる問題に取り組みながら、私はこれに遭遇しました。 UISearchDisplayControllerを使用しているときに、検索バーをナビゲーションバー(下ではなく)にinにする必要があります。
検索バーをナビゲーションバーに配置するのは難しくありません( ISearchBarおよびUINavigationItem を参照)。ただし、UISearchDisplayControllerは、検索バーが常にナビゲーションバーの下にあると想定し、(ここで説明したように)検索の入力時にナビゲーションバーを非表示にすることを要求するため、物事はひどく見えます。さらに、UISearchDisplayControllerは、検索バーを通常よりも明るくします。
私は解決策を見つけました。その秘Theは、UISearchDisplayControllerをUISearchBarの制御から完全に(反直感的に)フック解除することです。 xibsを使用する場合、これは検索バーインスタンスを削除するか、少なくともコンセントを外すことを意味します。次に、独自のUISearchBarを作成します。
- (void)viewDidLoad
{
[super viewDidLoad];
UISearchBar *searchBar = [[[UISearchBar alloc] init] autorelease];
[searchBar sizeToFit]; // standard size
searchBar.delegate = self;
// Add search bar to navigation bar
self.navigationItem.titleView = searchBar;
}
ユーザーが検索バーをタップしたときに、検索表示コントローラーを手動でアクティブにする必要があります(-searchBarShouldBeginEditing:
)ユーザーが検索を終了したときに検索バーを手動で閉じます(-searchDisplayControllerWillEndSearch:
)。
#pragma mark <UISearchBarDelegate>
- (BOOL)searchBarShouldBeginEditing:(UISearchBar *)searchBar {
// Manually activate search mode
// Use animated=NO so we'll be able to immediately un-hide it again
[self.searchDisplayController setActive:YES animated:NO];
// Hand over control to UISearchDisplayController during the search
searchBar.delegate = (id <UISearchBarDelegate>)self.searchDisplayController;
return YES;
}
#pragma mark <UISearchDisplayDelegate>
- (void) searchDisplayControllerDidBeginSearch:(UISearchDisplayController
*)controller {
// Un-hide the navigation bar that UISearchDisplayController hid
[self.navigationController setNavigationBarHidden:NO animated:NO];
}
- (void) searchDisplayControllerWillEndSearch:(UISearchDisplayController
*)controller {
UISearchBar *searchBar = (UISearchBar *)self.navigationItem.titleView;
// Manually resign search mode
[searchBar resignFirstResponder];
// Take back control of the search bar
searchBar.delegate = self;
}
iOS 7は少し物事を台無しにします...私にとってこれは完全に機能しました:
/**
* Overwrite the `setActive:animated:` method to make sure the UINavigationBar
* does not get hidden and the SearchBar does not add space for the statusbar height.
*
* @param visible `YES` to display the search interface if it is not already displayed; NO to hide the search interface if it is currently displayed.
* @param animated `YES` to use animation for a change in visible state, otherwise NO.
*/
- (void)setActive:(BOOL)visible animated:(BOOL)animated
{
[[UIApplication sharedApplication] setStatusBarHidden:YES];
[self.searchContentsController.navigationController setNavigationBarHidden:YES animated:NO];
[super setActive:visible animated:animated];
[self.searchContentsController.navigationController setNavigationBarHidden:NO animated:NO];
[[UIApplication sharedApplication] setStatusBarHidden:NO];
}
ステータスバーを表示/非表示にする理由
本当にすてきなソリューションですが、iOS6でアプリがクラッシュしていました。動作させるには、次の変更を行う必要がありました。
@implementation ICSearchDisplayController
- (void)setActive:(BOOL)visible animated:(BOOL)animated
{
if (visible == YES) {
[super setActive:visible animated:animated];
[self.searchContentsController.navigationController setNavigationBarHidden:NO animated:NO];
} else {
[super setActive:NO animated:NO];
}
}
これは私にとってそれを解決するようです。 iOS5/6.1の両方でテスト済み。視覚的な問題はありません。
- (void)viewDidAppear
{
[super viewDidAppear];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillAppear:) name:UIKeyboardWillShowNotification object:nil];
}
-(void)viewWillDisappear:(BOOL)animated{
[super viewWillDisappear:animated];
[[NSNotificationCenter defaultCenter] removeObserver:self];
}
- (void)keyboardWillAppear:(NSNotification *)notification
{
[self.navigationController setNavigationBarHidden:NO animated:NO];
}
-(void)viewDidLayoutSubviews{
[self.navigationController setNavigationBarHidden:NO animated:NO];
}
最善の解決策は、UISearchDisplayControllerを自分で実装することだと思います。
それは難しくありません。 UIViewControllerにUISearchBarDelegateを実装し、検索結果を表示するUITableViewを含めるだけです。
私はViewControllerにカスタムナビゲーションバーを追加していましたが、これは検索で非表示になっていたのですが、すぐにはあまり良くない修正でした
- (void)searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText{
[self.view addSubview:_navBar];
}
_navBarはプログラムで追加されたUINavigationBarです。これにより、ナビゲーションバーが非表示になりました。
Jrcが指摘したように、「UISearchDisplayControllerを任意のUISearchBarの制御から外す」は私にとってはうまくいくようです。 UISearchDisplayControllerを作成するときにパラメーターとしてnilを渡すと、ナビゲーションバーは常に表示されたままになります。
searchDisplayController = [[UISearchDisplayController alloc] initWithSearchBar:nil contentsController:self];
@Pavelは完璧に機能します。ただし、これをUIPopoverControllerに入れようとしていたので、検索バーのテキストフィールドが最初のレスポンダーになったときにフィールドのテキストがわずかにプッシュされ、少しthatいように見えるので、super
を呼び出して修正しましたanimated
をNO
に設定したメソッド。
Stigi answerに追加したかっただけです。検索をキャンセルして再び検索を開始すると、検索結果テーブルはタッチに反応しないため、次の行を追加する必要があります
self.searchResultsTableView.alpha = 1;
更新されたコードは次のように見えます
- (void)setActive:(BOOL)visible animated:(BOOL)animated;
{
if(self.active == visible) return;
if (visible) {
[self.searchContentsController.navigationController setNavigationBarHidden:YES animated:NO];
[super setActive:visible animated:animated];
[self.searchContentsController.navigationController setNavigationBarHidden:NO animated:NO];
self.searchResultsTableView.alpha = 1;
[self.searchBar becomeFirstResponder];
} else {
[super setActive:visible animated:animated];
[self.searchBar resignFirstResponder];
}
}