带有displaysSearchBarInNavigationBar的UISearchDisplayController使用navigationBar.translucent = false推送结果视图

时间:2013-09-26 21:41:25

标签: ios ios7 uisearchdisplaycontroller

我正在使用UISearchDisplayController和新的ios 7功能displaysSearchBarInNavigationBar和不透明的导航栏。搜索显示控制器似乎错误地定位了它的视图。

我尝试插入委托方法和重新定位,但我无法获得初始位置,也不能在旋转时。此外,这似乎是一个草率的解决方案。

with no text in search bar

with text in search bar

5 个答案:

答案 0 :(得分:19)

刚刚启用"在Opaque Bars"在视图控制器的故事板中,或者如果你想编码。然后添加以下行。你的好:):

self.edgesForExtendedLayout = UIRectEdgeAll;
self.extendedLayoutIncludesOpaqueBars = YES;

答案 1 :(得分:0)

我有同样的问题,我已经用这种方式解决了:

  1. 子类UISearchDisplayController将UISearchBar包含在适用于iOS 6和7的NavigationBar中。我已覆盖:
  2. 
        -(void)setActive:(BOOL)visible animated:(BOOL)animated
        {
            if (SYSTEM_VERSION_LESS_THAN(@"7")) {
                if(self.active == visible) return;
    
                [self.searchContentsController.navigationController setNavigationBarHidden:NO animated:NO];
    
                if (visible) {
                    [self.searchBar becomeFirstResponder];
                } else {
                    [self.searchBar resignFirstResponder];
                }
            } else {
                self.searchContentsController.view.frame = CGRectMake(0, 0, kCurrentScreenWidth, kCurrentScreenHeight);
                [super setActive:visible animated:animated];
            }
        }
    
    

    2.在UISearchDisplayDelegate中我添加了这个:

    
        - (void) searchDisplayController:(UISearchDisplayController *)controller didShowSearchResultsTableView:(UITableView *)tableView {
            // iOS7 Hack
            if (SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(@"7")) {
                controller.searchResultsTableView.contentInset = UIEdgeInsetsMake(0.f, 0.f, 0.f, 0.f);
            }
    
        }
    
        - (BOOL) searchDisplayController:(UISearchDisplayController *)controller shouldReloadTableForSearchString:(NSString *)searchString
        {
            // -- iOS 7 Hack
    
            if (SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(@"7")) {
                controller.searchResultsTableView.frame = CGRectMake(0, 64, kCurrentScreenWidth, kCurrentScreenHeight-64);
                [controller.searchContentsController.view setNeedsLayout];
            }
        }
    
    

答案 2 :(得分:0)

我遇到了同样的问题,经过几个小时的搜索,我决定查看视图层次结构。似乎searchBar的超级视图(也是暗视图)的y原点为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;
}

答案 3 :(得分:0)

我在网上无休止地搜索这个问题的解决方案,但没有任何建议在我的情况下工作。重置searchResultsTable的框架不起作用,因为它的origin.y已经是0.更改contentInset类型的工作,但没有修复灰色的重叠视图,并导致底部(和条形图)的表滚动视图出现问题。我最终得到了一个更好的工作黑客,虽然它并不完全理想,因为视图的帧移位很明显,但至少定位是正确的。

使用Reveal.app,我能够深入了解UISearchDisplayController的视图层次结构,以弄清楚发生了什么,这就是我的案例中的结果:

UISearchDisplayControllerContainerView
    - UIView (0,0,320,504)
        - UISearchResultsTableView
    - UIView (0,20,320,44)
    - UIView (0,64,320,440)
        - _UISearchDisplayControllerDimmingView

我以编程方式执行所有操作,因此不确定NIB的解决方法。以下是我的viewDidLoad方法中如何设置UISearchBar和UISearchDisplayController的基础知识:

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执行它的短暂延迟布局的东西。

答案 4 :(得分:0)

1.使用Reveal,找到封面层,发现是_UISearchDisplayControllerDimmingView

2.找到图层,修改相应的图框,可以在地图上找到dimmingview与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);
}