简体   繁体   English

只要下一个模态显示,就会关闭或删除以前模态显示的视图控制器

[英]Dismiss or remove previous modally presented view controller as soon as the next one appear modally

My target include a lot view need to present different view modally base on each user action. 我的目标包括很多视图需要根据每个用户操作以模态方式呈现不同的视图。 Here what I want to do to get cleaner view hierarchy and better user experience. 这就是我想要做的更清晰的视图层次结构和更好的用户体验。

  1. Root View Controller present First View Controller modally Root View Controller以模态方式呈现First View Controller
  2. When I clicked button on the First View Controller, then the Second View Controller appear modally over it. 当我单击第一视图控制器上的按钮时,第二视图控制器以模态方式显示在它上面。
  3. As soon as the Second View Controller did appear, I want to dismiss or remove the first one from view hierarchy. 第二个视图控制器出现后,我想从视图层次结构中解除或删除第一个视图控制器。

Can I do that? 我能这样做吗? If so , how should i do it? 如果是这样 ,我该怎么办?

If not , what is the right way to solve this out cause I will present many modally presented view controllers over each view. 如果没有 ,解决这个问题的正确方法是什么,我将在每个视图上呈现许多模态呈现的视图控制器。 I think even if I want to dismiss current view, the previous one will still remain appear when current one dismiss. 我想即使我想要忽略当前的观点,前一个观点仍然会在当前观点被忽略时出现。

UPDATE : 更新:

VC1 (Root) > VC 2 (which was present modally) > VC 3 (which was present modally over VC 2) VC1(Root)> VC 2(模态存在)> VC 3( 在VC 2上以模态存在)

When i dismiss VC3 , the VC2 is still on view memory. 当我关闭VC3VC2仍然在视图内存上。 So, I don't want to appear VC2 as soon as I dismiss VC3 and instead I want to see VC1 by removing or dismissing VC2 from view hierarchy. 因此,我不想在我解除VC3立即出现VC2 ,而是希望通过从视图层次结构中删除或解除VC2来查看VC1

在此输入图像描述

WANT : At the image, when I dismiss the blue,I don't want see the pink in my view memory and I want to remove it as soon as the blue one appear. 想要 :在图像中,当我解雇蓝色时,我不希望在我的视图记忆中看到粉红色,我想在蓝色出现时立即将其删除。

That's what i want to do. 这就是我想要做的。

Any Help?Thanks. 任何帮助?谢谢。

So, let's assume that you have a storyboard similar to: 所以,我们假设你有一个类似于的故事板:

在此输入图像描述

What should happens is: 应该发生的是:

  • Presenting the the second ViewController (from the first ViewController). 呈现第二个ViewController(来自第一个ViewController)。
  • Presenting the the third ViewController (from the second ViewController). 呈现第三个ViewController(来自第二个ViewController)。
  • dismissing to the first ViewController (from the third ViewController). 解雇第一个ViewController(来自第三个ViewController)。

In the third ViewController button's action: 在第三个ViewController按钮的动作中:

@IBAction func tapped(_ sender: Any) {
    presentingViewController?.presentingViewController?.dismiss(animated: true, completion: nil)
}

As you can see, by accessing the presentingViewController of the current ViewController, you can dismiss the previous hierarchy of the view controllers: 正如你所看到的,通过访问presentingViewController当前视图控制器,你可以关闭该视图控制器以前的层次结构:

The view controller that presented this view controller. 提供此视图控制器的视图控制器。

By implementing presentingViewController?.presentingViewController? 通过实现presentingViewController?.presentingViewController? that means that: the presented of the presented current ViewController :) 这意味着:呈现当前的ViewController :)

It might seem a little bit confusing, but it is pretty simple. 这看起来有点混乱,但很简单。

So the output should be like (I added background colors to the viewControllers -as vc1: orange, vc2: black and vc3: light orange- to make it appears clearly): 所以输出应该是这样的(我为viewControllers添加了背景颜色-as vc1:orange,vc2:black和vc3:light orange-以使其显得清晰):

在此输入图像描述

EDIT: 编辑:

If you are asking to remove the ViewController(s) in the middle (which in this example the second ViewController), dismiss(animated:completion:) does this automatically: 如果要求在中间删除ViewController(在本例中为第二个ViewController),则dismiss(animated:completion :)会自动执行此操作:

If you present several view controllers in succession, thus building a stack of presented view controllers, calling this method on a view controller lower in the stack dismisses its immediate child view controller and all view controllers above that child on the stack. 如果连续呈现多个视图控制器,从而构建一堆呈现的视图控制器,则在堆栈中较低的视图控制器上调用此方法会解除其直接子视图控制器以及堆栈上该子视图上方的所有视图控制器。 When this happens, only the top-most view is dismissed in an animated fashion; 发生这种情况时,只有最顶层的视图以动画方式被删除; any intermediate view controllers are simply removed from the stack. 任何中间视图控制器都可以从堆栈中删除。 The top-most view is dismissed using its modal transition style, which may differ from the styles used by other view controllers lower in the stack. 最顶层的视图使用其模态过渡样式被忽略,这可能与堆栈中较低的其他视图控制器使用的样式不同。

Referring to what are you asking: 参考你在问什么:

I think even if I want to dismiss current view, the previous one will still remain appear when current one dismiss. 我想即使我想要忽略当前的观点,前一个观点仍然会在当前观点被忽略时出现。

I think that appears clearly on the UI (and I find it ok), but as mentioned in the dismiss documentation discussion, both the third and the second will be removed from the stack. 我认为在UI上显而易见(我发现它没问题),但正如在dismiss文档讨论中所提到的,第三个和第二个都将从堆栈中删除。 That's the right way. 那是正确的方法。

What you want is an "unwind segue": 你想要的是一个“放松segue”:

https://developer.apple.com/library/archive/featuredarticles/ViewControllerPGforiPhoneOS/UsingSegues.html#//apple_ref/doc/uid/TP40007457-CH15-SW8 https://developer.apple.com/library/archive/featuredarticles/ViewControllerPGforiPhoneOS/UsingSegues.html#//apple_ref/doc/uid/TP40007457-CH15-SW8

https://developer.apple.com/library/archive/technotes/tn2298/_index.html https://developer.apple.com/library/archive/technotes/tn2298/_index.html

It allows you to dismiss multiple view controllers at the same time, without having to know how many there are in the stack. 它允许您同时关闭多个视图控制器,而无需知道堆栈中有多少个。

In VC1 you would implement an IBAction called (for instance) unwindToRoot . 在VC1中,您将实现一个名为(例如) unwindToRootIBAction Then in the storyboard for VC3, you wire up your Done button to the Exit object and choose the unwindToRoot action. 然后在VC3的故事板中,将“完成”按钮连接到“ Exit对象,然后选择unwindToRoot操作。

When that button is pressed, the system will dismiss all the view controllers it needs to bring you back to VC1. 按下该按钮后,系统将关闭所需的所有视图控制器,以便将您带回VC1。

This is better than calling presentingViewController?.presentingViewController?.dismiss() , because VC3 doesn't need to know anything about the view controller hierarchy underneath it. 这比调用presentingViewController?.presentingViewController?.dismiss()更好,因为VC3不需要知道它下面的视图控制器层次结构。

Here is my opinion in different perspective, 以下是我对不同角度的看法,

  1. Root View Controller present Second View Controller Root View Controller提供第二视图控制器
  2. Add FirstView onto Second View 将FirstView添加到第二个视图
  3. Dismiss FirstView Controller when button pressed. 按下按钮时关闭FirstView控制器。

在此输入图像描述

Second View Controller, 第二视图控制器,

class ViewController: UIViewController, FirstViewControllerProtocol {

    weak var firstViewController: FirstViewController?

    override func viewDidLoad() {
        super.viewDidLoad()

        print("Not initiated: \(firstViewController)")

        firstViewController  = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "FirstViewController") as? FirstViewController
        addChildViewController(firstVC!)
        firstViewController?.delegate = self
        view.addSubview((firstViewController?.view)!)

        print("Initiated: \(firstViewController)")
    }

    func dismiss() {
        firstViewController?.view.removeFromSuperview()
        firstViewController?.removeFromParentViewController()

    }
}

FirstViewController, FirstViewController,

protocol FirstViewControllerProtocol {
    // Use protocol/delegate to communicate within two view controllers
    func dismiss() 
}

class FirstViewController: UIViewController {

    var delegate: FirstViewControllerProtocol?

    override func viewDidLoad() {
        super.viewDidLoad()
    }

    @IBAction func dismiss(_ sender: Any) {
        delegate?.dismiss()
    }

    deinit {
        print("BYE")
    }

}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 关闭从模态呈现的视图控制器翻转的视图控制器 - Dismiss view controller flipped from modally presented view controller 将以模态形式呈现的视图控制器转移给其他基础视图控制器 - dismiss a modally presented view controller to a different underlying view controller 关闭以模态显示的视图使标签栏控制器(种类)重置 - Dismiss Modally presented view makes tab bar controller (kind of) reset 两个模态呈现的视图控制器-都关闭 - Two modally presented view controllers - dismiss both 在以模态表示的View Controller上调用viewDidLoad - Calling viewDidLoad on a View Controller presented Modally willRotateToInterfaceOrientation未在模态呈现的视图控制器中调用 - willRotateToInterfaceOrientation not being called in a modally presented view controller 模态显示/关闭视图控制器时通知? - Notification when view controller is presented modally/dismissed? Swift尝试以模态形式呈现一个活动控制器[Current view controller],即使所呈现的控制器是另一个 - Swift tried to present modally an active controller [Current view controller] even though the presented controller is another one 从模态呈现的视图控制器导航到根视图控制器 - Navigate to root view-controller from modally presented view controller 取消双模态呈现视图控制器的父视图控制器 - Dismissing parent view controller of double modally presented view controller
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM