我正在使用 UISearchDisplayController 和新的 ios 7 功能显示SearchBarInNavigationBar 和不透明的导航栏。搜索显示控制器似乎将其视图定位不正确。
我尝试插入委托方法并重新定位,但我无法正确获得初始位置,旋转时也无法获得。此外,这似乎是一个草率的解决方案。
我正在使用 UISearchDisplayController 和新的 ios 7 功能显示SearchBarInNavigationBar 和不透明的导航栏。搜索显示控制器似乎将其视图定位不正确。
我尝试插入委托方法并重新定位,但我无法正确获得初始位置,旋转时也无法获得。此外,这似乎是一个草率的解决方案。
只需在情节提要中为您的视图控制器启用“在不透明条下”,或者如果您喜欢编码。然后添加以下行。你的好:)
self.edgesForExtendedLayout = UIRectEdgeAll;
self.extendedLayoutIncludesOpaqueBars = YES;
我有同样的问题,我已经以这种方式修复:
-(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]; } }
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;
}
我在网上无休止地搜索这个问题的解决方案,但在我的情况下没有任何推荐的方法。重置 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 完成布局之后应用我的位置调整。
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);
}