当不是模态时,放开segue并不会解除自适应popup窗口的显示

更新iOS 9testing版:苹果可能已经修复了iOS 9的这个问题。如果你在iOS 8的这个问题上工作(编辑),请确保它在iOS 9上也能正常工作。

在故事板中,我创build了一个popup式演示文稿segue,用于显示button中的导航和视图控制器,以及创build一个展开的细节。

如预期的那样,在纵向方向上,模式(全屏)演示被展开/消除。

在横向方向上,展开的顺序也被调用,但是展开的展示不会被自动解除。

我错过了什么东西吗? 我必须自己解除stream行的演示文稿吗?

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)__unused sender { if ([[segue identifier] isEqualToString:@"showSelectBookChapter"]) { UINavigationController *navigationController = segue.destinationViewController; if ([navigationController.topViewController isKindOfClass:[BIBLESelectViewController class]]) { BIBLESelectViewController *selectViewController = (BIBLESelectViewController *)navigationController.topViewController; selectViewController.initialBookChapterVerse = self.bookChapterVerse; } } } - (IBAction)unwindToBIBLEChapterViewController:(UIStoryboardSegue *)segue { if ([segue.identifier isEqualToString:@"unwindToBIBLEChapterViewController"]) { if ([segue.sourceViewController isKindOfClass:[BIBLESelectViewController class]]) { BIBLESelectViewController *sourceViewController = (BIBLESelectViewController *)segue.sourceViewController; self.bookChapterVerse = sourceViewController.selectedBookChapterVerse; [self.tableView reloadData]; } } } 

故事板的场景和赛格 更新:在查看gabbler的示例代码之后,我已经将问题缩小到单视图应用程序中的popup视图,而不是在主详图应用程序中。

更新2:为了回答Luis提出的问题,下面是层次结构(为简单起见,省略了导航控制器)

  • 分割视图控制器
    • 主视图控制器
    • 详细视图控制器
      • 章节视图控制器(模式页面)
        • select视图控制器(展开到章节视图控制器的有问题的popup窗口,但不排除)

正如我在之前的更新中提到的那样,我创build了一个新的主/从模板,并直接从详细视图中的一个button(直接显示了一个popup窗口)。 它不会解雇。

我也遇到了这个问题。 我从主视图控制器(UISplitViewController)以模态方式(作为表单)呈现视图控制器。 这个问题只发生在iPad上(可能也是横向模式的iPhone 6+,但我没有检查它)。 我在unwind action方法(使用Swift)中完成了以下工作,并且效果很好。

 if !segue.sourceViewController.isBeingDismissed() { segue.sourceViewController.dismissViewControllerAnimated(true, completion: nil) } 

如果您导航控制器中embedded的视图控制器作为popup窗口继续播放,则相应的展开无法closurespopup窗口。

这是一个错误-[UINavigationController segueForUnwindingToViewController:fromViewController:identifier] 。 embedded式导航控制器应该提供一个会消除popup的segue,但它不会。 然后修复是覆盖这个,并提供一个工作segue,我们可以从embedded式视图控制器。

下面是一个局部解决scheme,它只处理展开到导航堆栈的顶部视图控制器:

 @implementation MyNavigationController - (UIStoryboardSegue *)segueForUnwindingToViewController:(UIViewController *)toViewController fromViewController:(UIViewController *)fromViewController identifier:(NSString *)identifier { if (toViewController == self.topViewController && fromViewController.presentingViewController == self) return [toViewController segueForUnwindingToViewController:toViewController fromViewController:fromViewController identifier:identifier]; else return [super segueForUnwindingToViewController:toViewController fromViewController:fromViewController identifier:identifier]; } @end 

它适用于横向/纵向iPad和横向/纵向iPhone的iOS 8。 逻辑应该足够强大,以在iOS 9上生存。

它必须是popOver segue的行为,在正常情况下或者我们经常需要popOver保持在视野中,如果segue显示重要的东西很烦人,我们只是因为旋转设备而丢失了这些信息,那么我猜测那是原生行为的原因。 所以如果我们想让它自动解散,我们必须由我们自己来行动,这是行得通的:

在detailViewController.m中的方法- (void)viewDidLoad中添加:

 [[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(orientationChanged:) name:UIDeviceOrientationDidChangeNotification object:[UIDevice currentDevice]]; 

然后创build这个方法:

 - (void) orientationChanged:(NSNotification *)note{ UIDevice * device = note.object; //CGRect rect = [[self view] frame]; switch(device.orientation) { default: [self dismissViewControllerAnimated:YES completion:nil]; break; }} 

你说在一个单一的视图发生你想要的,但我从来没有见过这种行为,当我使用popOver。

mbeaty的解决scheme非常好,但正如其他人所指出的,这个bug似乎已经在iOS 9中得到了解决,而且在通用设备devise中也不太适用。 我已经调整了他的答案来处理这两种情况。 这里是代码:

 @IBAction func yourUnwindSegue(segue: UIStoryboardSegue) { if #available(iOS 9, *) { return // bug fixed in iOS 9, just return and let it work correctly } // do the fix for iOS 8 bug // access your SplitViewController somehow, this is one example let appDelegate = UIApplication.sharedApplication().delegate as! AppDelegate let splitVC = appDelegate.window!.rootViewController as! YourSplitViewController // if the source isn't being dismissed and the splitView isn't // collapsed (ie both windows are showing), do the hack to // force it to dismiss if !segue.sourceViewController.isBeingDismissed() && splitVC.collapsed == false { segue.sourceViewController.dismissViewControllerAnimated(true, completion: nil) } } 

这首先检查如果iOS 9正在运行,并只是退出,因为该错误似乎是固定的。 这将防止多个视图被解雇的问题。 此外,为了确保此修复只在splitView显示两个窗口(为了使其仅在横向上的iPad和iPhone 6 Plus以及未来的设备上发生)完成,我添加了检查以确保它没有折叠。

我没有详尽地检查这个,但它似乎工作。 也不是说我的应用程序设置为iOS 7的分钟,我不知道这个bug是否存在,所以你可能需要看看,如果你支持下面的iOS 8。