6

iOS 9 测试版更新:Apple 可能已针对 iOS 9 修复此问题。如果您针对 iOS 8 解决此问题,请确保它在 iOS 9 上也能正常工作。

在 storyboard 中,我创建了一个 popover 演示 segue 来从一个按钮呈现一个导航和视图控制器,以及创建一个 unwind segue。

在纵向中,模态(全屏)演示文稿按预期展开/关闭。

在横向,展开segue 也会被调用,但是popover 演示不会自动关闭。

我错过了连接的东西吗?我必须自己关闭弹出窗口演示吗?

- (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 的示例代码后,我已将问题缩小到在单视图应用程序中弹出窗口关闭正常,但在主从应用程序中没有。

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

  • 拆分视图控制器
    • 主视图控制器
    • 细节视图控制器
      • 章节视图控制器(模态页表)
        • 选择视图控制器(有问题的弹出框展开到章节视图控制器,但不会关闭)

正如我在之前的更新中提到的,我创建了一个新的主/详细模板,并直接从详细视图(中的一个按钮)显示了一个弹出框。它不会解雇。

4

4 回答 4

11

我也遇到了这个问题。我从主视图控制器 (UISplitViewController) 以模态方式(作为表单)呈现视图控制器。这个问题只发生在 iPad 上(可能 iPhone 6+ 也处于横向模式,但我没有检查)。我最终在我的展开操作方法(使用 Swift)中执行了以下操作,并且效果很好。

if !segue.sourceViewController.isBeingDismissed() {
    segue.sourceViewController.dismissViewControllerAnimated(true, completion: nil)
}
于 2015-03-01T11:51:55.003 回答
4

如果您嵌入导航控制器的视图控制器中选择弹出框,则相应的展开无法关闭弹出框。

这是-[UINavigationController segueForUnwindingToViewController:fromViewController:identifier]. 嵌入导航控制器应该提供一个 segue 来关闭弹出框,但它没有。然后解决方法是覆盖它并提供一个工作 segue,我们可以从嵌入式视图控制器中获得它。

这是一个仅处理展开到导航堆栈的顶视图控制器的部分解决方案:

@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 上生存。

于 2015-08-10T05:44:17.633 回答
1

它是/必须是 popOver segue 的一种行为,在正常情况下或经常我们需要 popOver 保持在视野中,如果 segue 显示一些重要的东西很烦人,我们只是因为我们旋转设备而丢失了该信息,我猜那是这种原生行为的原因。因此,如果我们想让它自动关闭,我们必须自己做出这种行为,这很有效:

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

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

然后创建这个方法:

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

你说在一个视图中会发生你想要的,但是当我使用 popOvers 时我从未见过这种行为。

于 2015-02-05T19:38:46.830 回答
0

mbeaty 的修复很棒,但正如其他人指出的那样,这个错误似乎知道在 iOS 9 中已修复,并且它也不适用于通用设备设计。我已经调整了他的答案来处理这两种情况。这是代码:

@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,我不知道这个错误是否存在,所以如果你支持低于 iOS 8,你可能需要研究它。

于 2016-09-23T06:47:43.343 回答