UISearchBar不会在UISplitviewController Master

时间:2016-09-07 12:08:41

标签: ios uisplitviewcontroller uisearchcontroller

我在UITableview,通用UISplitviewController应用中有一个非常标准的iOS9设置为主控制器。

同样,标准票价,我插入一个UISearchBar作为表格的标题。

self.searchController = [[UISearchController alloc] initWithSearchResultsController:nil];
self.searchController.searchResultsUpdater = self;
self.searchController.dimsBackgroundDuringPresentation = NO;
self.searchController.hidesNavigationBarDuringPresentation = NO;

[self.searchController.searchBar sizeToFit];
self.tableView.tableHeaderView = self.searchController.searchBar;

self.definesPresentationContext = YES;

无需在iPhone上显示我的其余代码,搜索和所有正常工作。我的问题是,在iPad上运行时,搜索栏不会获得焦点或显示键盘。没有回应,似乎没有接受。甚至不响应以编程方式尝试becomeFirstResponder

什么都没发生。

搜索栏可见且放置正确,没有底衬或叠加问题。

它在iPhone上运行正常。接收触摸,呈现键盘,搜索工作。据推测,UISplitviewController崩溃时,呈现方式存在重大差异。通过几个小时的搜索,浏览文档和我遇到的每个教程,我都没有找到类似的经历令人惊讶。

附加说明:如果我使用多任务处理将分割视图缩小为在iPad上折叠,则搜索栏会起作用,与iPhone上的相同。它肯定与拆分视图的折叠状态有关。

更新:(越来越近)

经过进一步的实验,我发现如果你在横向上启动应用程序,搜索栏就可以在iPad上运行。在纵向模式下,我的主控制器被隐藏。它通过选择displayModeButtonItem滑入,该leftBarButtonItem设置为详细控制器的definesPresentationContext。那是在searchBar中断并且不再响应触摸的时候。

如果我从风景开始,然后旋转到肖像,它也会停止工作。旋转回景观并不能解决问题。一旦发生故障,它会一直保持破损状态直到重新启动。

我尝试将viewWillAppear移动到主控制器的iPhone方法,但这没有效果。

进一步更新:

另一个意想不到的情况是iPhone 6plus上的搜索栏完全没有问题。无论方向,折叠或否,都可以工作,无论它开始处于什么状态都无关紧要。我希望在横向时这与iPad相同。完全适用于viewDidLayoutSubviews

我仍然没有想到这一点。我最近尝试修复,我将所有搜索控制器初始化移动到if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) { splitViewController.preferredDisplayMode = UISplitViewControllerDisplayModeAllVisible; } 方法。没有任何改变。

另外,我注意到当搜索处于活动状态时,键盘在屏幕上,如果我旋转iPad,键盘会消失但搜索栏仍然有效。起初我没有意识到,然后我看到取消按钮仍然显示。它不会接受触摸而且没有键盘,但它显然仍然是第一响应者。

示例项目上传到GitHub: Github Repository

注意 - 在我将UISplitview Delegate方法添加到项目之前没有问题。我想立即将此问题添加到我的问题中,因此,我还没有尝试确切地看到这些委托方法如何影响搜索栏,但显然问题是在某处创建的。

更新

我尝试了一些更改但没有成功。

  • 将搜索栏移至栏目标题。没有快乐。
  • 将搜索栏放在UIView中作为内容视图。没有快乐。
  • 删除搜索栏消失,重新插入确实出现。没有快乐。
  • 操纵搜索栏框的大小以确保其不被剪裁。没有快乐。

我还查看了探查器中的视图层次结构,搜索栏是顶级的,没有被其他任何内容覆盖。

Final Wrap:

@tomSwift解决方法在iPad上纠正了我的问题。在进一步测试中,我发现它破坏了我的iPhone UI。据推测,这更多地是我自己的设置和创建主/细节视图控制器的时间问题。似乎一些重要的对象不再及时创建,因为可能还没有详细视图控制器。我通过将关键项目移动到App Delegate来解决问题,但这变得笨拙并且我无法轻易缩小范围,因此我修复了以下内容:

 $('#example').on('click', '.alertShow', function () {
            var id=$(this).attr("id");
            alert(id);
    }

可能会有一个更优雅的解决方案,但这需要我足够的时间。现在一切都有效。雷达提交 - 28304096

2 个答案:

答案 0 :(得分:4)

这显然是UISplitViewController和/或UISearchController中的错误。当然用Apple提交雷达并附上你的代码样本。

我认为该错误涉及UISplitViewController.displayMode UISplitViewControllerDisplayModeAutomatic。当我将preferredDisplayMode更改为UISplitViewControllerDisplayModeAllVisible时,一切都会开始起作用:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    // Override point for customization after application launch.
    UISplitViewController *splitViewController = (UISplitViewController *)self.window.rootViewController;
    UINavigationController *navigationController = [splitViewController.viewControllers lastObject];
    navigationController.topViewController.navigationItem.leftBarButtonItem = splitViewController.displayModeButtonItem;
    splitViewController.delegate = self;
    splitViewController.preferredDisplayMode = UISplitViewControllerDisplayModeAllVisible;

    return YES;
}

这个改变的主要是iPad上的肖像画的默认布局,我理解这可能不太理想。我还最初将preferredDisplayMode设置为UISplitViewControllerDisplayModeAllVisible,然后将其设置回UISplitViewControllerDisplayModeAutomatic;这很好用,直到屏幕方向改变 - 然后它再次破裂。你可能会在这条道路上走得更远。

我还在AppDelegate中添加了以下内容,以强制搜索控制器停用displayMode更改。 (我还必须在MasterViewController上公开公开searchController属性。)

- (void)splitViewController:(UISplitViewController *)svc willChangeToDisplayMode:(UISplitViewControllerDisplayMode)displayMode {

    UINavigationController *navigationController = [svc.viewControllers firstObject];
    MasterViewController* mvc = (MasterViewController*) navigationController.topViewController;
    [mvc.searchController setActive: NO];
}

答案 1 :(得分:1)

使用您的项目并发现问题是您的搜索控制器永远不会设置为活动状态。因此,我将UISplitViewController子类化并使其成为自己的委托,以便在模式更改时通知子视图控制器,因此您可以在正确的时间将其设置为活动状态。

使用此委托方法创建通知:

- (void)splitViewController:(UISplitViewController *)svc willChangeToDisplayMode:(UISplitViewControllerDisplayMode)displayMode {
    NSLog(@"WILL CHANGE TO DISPLAY MODE: %ld", (long)displayMode);

    NSNumber *displayNumber = [NSNumber numberWithInteger:displayMode];
    NSDictionary *userInfo = @{ @"displayMode": displayNumber };
    NSNotification *modeChangedNotif = [NSNotification notificationWithName:@"modeChanged" object:nil userInfo:userInfo];
    [[NSNotificationCenter defaultCenter] postNotification:modeChangedNotif];
}

然后在您的MasterViewController中,您可以在viewDidLoad

中执行此操作
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(modeChanged) name:@"modeChanged" object:nil];

在该方法中,您可以检查特定的displayMode枚举,但为了让它正常工作,我只是做了:

- (void) modeChanged {
    [self.searchController setActive:YES];
}