新しいios 7機能displaySearchBarInNavigationBarと不透明なナビゲーションバーでUISearchDisplayControllerを使用しています。検索ディスプレイ コントローラーがビューを正しく配置していないようです。
デリゲート メソッドにプラグインして再配置しようとしましたが、初期位置を正しく取得できず、回転しても取得できません。さらに、これはずさんな解決策のようです。
新しいios 7機能displaySearchBarInNavigationBarと不透明なナビゲーションバーでUISearchDisplayControllerを使用しています。検索ディスプレイ コントローラーがビューを正しく配置していないようです。
デリゲート メソッドにプラグインして再配置しようとしましたが、初期位置を正しく取得できず、回転しても取得できません。さらに、これはずさんな解決策のようです。
View Controllerのストーリーボードで「Under Opaque Bars」を有効にしただけ、またはコーディングしたい場合は、以下の行を追加してください。あなたの良い:)
self.edgesForExtendedLayout = UIRectEdgeAll;
self.extendedLayoutIncludesOpaqueBars = YES;
同じ問題があり、何時間も答えを探した後、ビュー階層を調べることにしました。淡色表示でもある searchBar のスーパービューの原点は 64、高さは 504 で、画面全体に表示されていないようです。なぜそうなのかはわかりません。それにもかかわらず、yを0に設定することになり、高さは画面の高さになりました。その後、y を元の値に戻します。そうしないと、コンテンツ テーブル ビューが歪んでしまいます。これは最善の解決策ではありませんが、何もしないよりはましです。これがお役に立てば幸いです。
- (void)searchDisplayControllerWillEndSearch:(UISearchDisplayController *)controller {
self.savedSearchTerm = nil;
UIView *dimmedView = controller.searchBar.superview;
CGRect frame = dimmedView.frame;
frame.origin.y = 64;
dimmedView.frame = frame;
[self.tableView reloadData];
}
- (void)searchDisplayControllerWillBeginSearch:(UISearchDisplayController *)controller {
UIView *dimmedView = controller.searchBar.superview;
CGRect frame = dimmedView.frame;
frame.origin.y = 0;
frame.size.height = 568;
dimmedView.frame = frame;
}
1. Reveal を使用し、カバー レイヤーを見つけて、_UISearchDisplayControllerDimmingView であることがわかりました。
2. レイヤーを検索し、対応するフレームを変更します。同じビューの searchResultsTableView サブレイヤーを使用してビューを調光することで、マップ上で見つけることができます。
- (void)searchDisplayControllerDidBeginSearch:(UISearchDisplayController *)controller {
for(UIView * v in controller.searchResultsTableView.superview.subviews)
{
if([v isKindOfClass:[NSClassFromString(@"_UISearchDisplayControllerDimmingView") class]])
{
v.frame = CGRectMake(0,20,320,400); // modify the frame
NSLog(@"--------- %@",[v class]);
}
}
3. 同様に、searchResultsTableView フレームを調整する必要がある場合は、次のコードを
- (void)searchDisplayController:(UISearchDisplayController *)controller didShowSearchResultsTableView:(UITableView *)tableView
{
tableView.frame =CGRectMake(0, 20, 320, 480-64-44);
}
この問題の解決策をオンラインで際限なく検索しましたが、私の場合は推奨されたものは何も機能しませんでした。origin.y がすでに 0 だったため、searchResultsTable のフレームをリセットしても機能しませんでした。ビューのフレームシフトが一時的に目立つため、完全に理想的ではありませんが、最終的にはより適切なハックを取得しましたが、少なくともその後の位置は正しいです。
Reveal.app を使用して、UISearchDisplayController のビュー階層を掘り下げて、何が起こっているのかを把握することができました。これが私の場合の結果でした。
UISearchDisplayControllerContainerView
- UIView (0,0,320,504)
- UISearchResultsTableView
- UIView (0,20,320,44)
- UIView (0,64,320,440)
- _UISearchDisplayControllerDimmingView
私はすべてをプログラムで行っているため、NIB の回避策についてはわかりません。メソッドで UISearchBar と UISearchDisplayController を設定する方法の基本は次のとおりですviewDidLoad
。
UISearchBar *searchBar = [[UISearchBar alloc] initWithFrame:CGRectMake(0, 0, CGRectGetWidth(self.view.bounds), 0)];
searchBar.autoresizingMask = UIViewAutoresizingFlexibleWidth;
searchBar.delegate = self;
[searchBar sizeToFit];
self.searchController = [[UISearchDisplayController alloc] initWithSearchBar:searchBar contentsController:self];
self.searchController.delegate = self;
self.searchController.searchResultsDataSource = self.searchDataSource;
self.searchController.searchResultsDelegate = self;
if ([self.searchController respondsToSelector:@selector(displaysSearchBarInNavigationBar)]) {
self.searchController.displaysSearchBarInNavigationBar = YES;
}
そして、この場合に機能した私のハック:
- (void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
if (SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(@"7.0")) {
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(fixSearchControllerPositionOnKeyboardAppear)
name:UIKeyboardWillShowNotification object:nil];
if (self.searchController.isActive) {
// the following is needed if you are return to this controller after dismissing the child controller displayed after selecting one of the search results
[self performSelector:@selector(fixSearchControllerPositionForiOS7) withObject:nil afterDelay:0];
}
}
}
- (void)viewDidDisappear:(BOOL)animated {
[super viewDidDisappear:animated];
[[NSNotificationCenter defaultCenter] removeObserver:self name:UIKeyboardWillShowNotification object:nil];
}
- (void)fixSearchControllerPositionForiOS7 {
UIView *view = self.searchController.searchResultsTableView.superview;
// only perform hack if the searchResultsTableView has been added to the view hierarchy
if (view) {
// The searchDisplayController's container view is already at 0,0, but the table view if shifted down 64px due to
// bugs with the subviews in iOS 7, so shift the container back up by that negative offset.
// This also fixes the position of the dimmed overlay view that appears before results are returned.
CGFloat yOffset = 64.0;
CGRect viewFrame = view.frame;
if (CGRectGetMinY(viewFrame) == 0) {
viewFrame.origin.y = -yOffset;
viewFrame.size.height += yOffset;
[UIView animateWithDuration:0.1 delay:0 options:UIViewAnimationOptionCurveEaseOut animations:^{
view.frame = viewFrame;
} completion:nil];
}
// we also need to adjust dimmed overlay view, so iterate through the search view controller's container
// view and make sure all subviews have their vertical origin set to 0
UIView *searchContainerView = view.superview;
for (NSInteger i = 0; i < [searchContainerView.subviews count]; i++) {
UIView *subview = searchContainerView.subviews[i];
if (CGRectGetMinY(subview.frame) > 0) {
CGRect subviewFrame = subview.frame;
CGFloat offset = CGRectGetMinY(subviewFrame);
subviewFrame.origin.y = 0;
if (offset == 20.0) {
// this subview is partially responsible for the table offset and overlays the top table rows, so set it's height to 0
subviewFrame.size.height = 0;
}
else {
// this subview is the dimmed overlay view, so increase it's height by it's original origin.y so it fills the view
subviewFrame.size.height += offset;
}
subview.frame = subviewFrame;
}
}
}
}
- (void)fixSearchControllerPositionOnKeyboardAppear {
// call hack to reset position after a slight delay to avoid UISearchDisplayController from overriding our layout fixes
[self performSelector:@selector(fixSearchControllerPositionForiOS7) withObject:nil afterDelay:0.1];
}
- (void)searchDisplayControllerWillBeginSearch:(UISearchDisplayController *)controller {
if (SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(@"7.0")) {
[self fixSearchControllerPositionForiOS7];
}
}
キーボードが表示されたときにオブザーバーを追加する必要がありました。これにより、UISearchDisplayController がサブビューを再レイアウトし、UISearchDisplayController がレイアウトを行った後に位置調整が確実に適用されるようにするための短い遅延が発生しました。