UISplitViewController - 在折叠模式下关闭/弹出代码中的详细视图控制器

UISplitViewController - dismiss / pop Detail View Controller in code in collapsed mode

自 iOS8 起,我们可以在紧凑型和常规设备上使用 UISplitViewController。这很棒,因为我不必为 iPhone 和 iPad 创建两个不同的情节提要,但是我遇到了一个问题。

如果拆分视图控制器打开 iPad(如果折叠 属性 为 NO),我可以简单地调用它以在左侧显示 MasterVC。

self.splitViewController.preferredDisplayMode = UISplitViewControllerDisplayModePrimaryOverlay;
[self.splitViewController.displayModeButtonItem action];

但是如果它在 iPhone 上(如果折叠 属性 是 YES),displayMode 将被忽略,并且不做任何事情。

我无法用 popToRootViewControllerAnimated 弹出 DetailVC,因为 DetailVC 有它自己的导航控制器。

如果 showDetail 提供的视图控制器没有类似 dismissViewControllerAnimated:completion: 的任何方法,Apple 如何期望我们在代码中以折叠模式显示 MasterVC(关闭 DetailVC)?您的帮助将不胜感激。谢谢

在不支持 "split" 模式的设备上,if

  1. 您想呈现 master 视图控制器而不是 detailUISplitViewController 第一次加载时,然后在您的委托 class (UISplitViewControllerDelegate) splitViewController:collapseSecondaryViewController:ontoPrimaryViewController: 方法中返回 YES 方法应该这样做:

    - (BOOL)splitViewController:(UISplitViewController *)splitViewController collapseSecondaryViewController:(UIViewController *)secondaryViewController ontoPrimaryViewController:(UIViewController *)primaryViewController {
        return YES;
    }
    
  2. 您想关闭 detail 视图控制器回到master,在特定事件之后(例如触摸按钮)。在这种情况下,您必须弹出 detail 视图控制器导航控制器:

    [detailViewController.navigationController.navigationController popToRootViewControllerAnimated:YES]
    

今天在尝试从拆分视图控制器中的详细视图弹出时遇到了类似的问题。

虽然我确定已接受的答案可以正常工作,但我发现另一种同样有效并且可能更简洁的方法是使用 unwind segue。

我在我想要 return 的主视图上设置了一个 unwind segue,然后从我想弹出的视图创建了一个 segue link 到 unwind segue(注意:假设你正在使用故事板)。

确保在要弹回的目标视图上设置 IBAction:

-(IBAction)prepareForUnwind:(UIStoryboardSegue *)segue { }

将出口连接到情节提要中的转场以进行展开转场。抱歉,我没有提供很多关于如何设置展开转场的细节,但是有很多教程可供使用。

然后在你想要关闭的控制器上,将一个 segue 连接到你要弹回的控制器的展开 segue。请务必命名 segue。

然后在你想关闭的视图控制器中触摸按钮,只需调用

[self performSegueWithIdentifier:@"unwindSegueName" sender:self];

这非常有效,避免了向后挖掘可能会更改的导航层次结构。

希望这对某人有用! 节日快乐!

谢谢 pNre!这是处理折叠时显示自定义后退按钮和未折叠时显示 displayModeButton 的代码。

lazy var backButtonItem: UIBarButtonItem = {
    UIBarButtonItem(image: UIImage(named: "backImage"), style: .plain, target: self, action: #selector(dismissAnimated))
}()

override func viewWillLayoutSubviews() {
    super.viewWillLayoutSubviews()

    guard let svc = splitViewController else { return }

    if svc.isCollapsed {
        navigationItem.leftBarButtonItem = backButtonItem
    } else {
        navigationItem.leftBarButtonItem = svc.displayModeButtonItem
    }
}

func dismissAnimated() {
    _ = navigationController?.navigationController?.popViewController(animated: true)
}

我将它放在 willLayoutSubviews() 而不是 viewDidLoad() 中,这样按钮将自适应更新,例如,对于 iPhone 7 Plus 和尺寸 [=22] 上的方向变化=] 更改,例如在 iPad.

的拆分视图中

如果我们处于折叠状态(iPhone 不包括 +sizes),这是我最终弹出 DetailVC 的方法,如果我们不处于折叠状态,show/hide MasterVC( iPad).

@IBAction func backTouchUp(_ sender: UIButton) {
    if let splitViewController = splitViewController,
        !splitViewController.isCollapsed {
        UIApplication.shared.sendAction(splitViewController.displayModeButtonItem.action!, to: splitViewController.displayModeButtonItem.target, from: nil, for: nil)
    } else {
        navigationController?.popViewController(animated: true)
    }
}