19

我正在使用 UISearchDisplayController 和新的 ios 7 功能显示SearchBarInNavigationBar 和不透明的导航栏。搜索显示控制器似乎将其视图定位不正确。

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

搜索栏中没有文字

在搜索栏中带有文本

4

5 回答 5

19

只需在情节提要中为您的视图控制器启用“在不透明条下”,或者如果您喜欢编码。然后添加以下行。你的好:)

self.edgesForExtendedLayout = UIRectEdgeAll;
self.extendedLayoutIncludesOpaqueBars = YES;
于 2014-04-03T14:50:54.833 回答
0

我有同样的问题,我已经以这种方式修复:

  1. 子类 UISearchDisplayController 在 iOS 6 和 7 的 NavigationBar 中有 UISearchBar。我已经覆盖:
    -(void)setActive:(BOOL)可见动画:(BOOL)动画
    {
        如果(SYSTEM_VERSION_LESS_THAN(@“7”)){
            如果(self.active == 可见)返回;

            [self.searchContentsController.navigationController setNavigationBarHidden:NO动画:NO];

            如果(可见){
                [self.searchBar 成为FirstResponder];
            } 别的 {
                [self.searchBar resignFirstResponder];
            }
        } 别的 {
            self.searchContentsController.view.frame = CGRectMake(0, 0, kCurrentScreenWidth, kCurrentScreenHeight);
            [超级setActive:可见动画:动画];
        }
    }

2.在 UISearchDisplayDelegate 我添加了这个:

    - (void) searchDisplayController:(UISearchDisplayController *)controller didShowSearchResultsTableView:(UITableView *)tableView {
        // iOS7 破解
        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 破解

        if (SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(@"7")) {
            controller.searchResultsTableView.frame = CGRectMake(0, 64, kCurrentScreenWidth, kCurrentScreenHeight-64);
            [controller.searchContentsController.view setNeedsLayout];
        }
    }

于 2013-10-30T13:31:37.607 回答
0

I had the same issue and after hours of searching for an answer, I decided to look through the view hierarchy. It seems that the superview of the searchBar, which is also the dimmed view, has a y origin of 64 and a height of 504, which is not populating the whole screen. Not sure why it's like that. Nevertheless, I ended up setting the y to 0 and it's height to the screen height. After which, I set its y back to the original value, or else your content table view will be distorted. It's not the best solution, but it's better than nothing. Hope this helps you.

- (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;
}
于 2013-12-05T03:46:25.763 回答
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;
}

在这种情况下,我的 hack 有效:

- (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 完成布局之后应用我的位置调整。

于 2014-02-01T02:07:45.623 回答
0

1.使用Reveal,找到覆盖层,发现是_UISearchDisplayControllerDimmingView

2.找到图层,修改对应的边框,通过dimmingview可以在地图上找到与searchResultsTableView子图层相同的view。

- (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的frame,在

- (void)searchDisplayController:(UISearchDisplayController *)controller didShowSearchResultsTableView:(UITableView *)tableView
{
    tableView.frame =CGRectMake(0, 20, 320, 480-64-44);
}
于 2016-08-15T07:06:15.753 回答