简体   繁体   English

导航时关闭视图控制器

[英]Dismiss view controller when navigating

I'm creating an IOS Application in swift and I found a pretty big problem in my case.我正在快速创建一个 IOS 应用程序,在我的案例中我发现了一个非常大的问题。

If I would do this in Android I would use fragments and just replace the current fragment to a new one, but nothing seem to be equal to fragment in swift, so.如果我在 Android 中执行此操作,我将使用片段并将当前片段替换为一个新片段,但在 swift 中似乎没有什么等同于片段,所以。

I start on view controller A and then I'm navigating to view controller B (The user should just pick their name in this view) and from BI want to navigate to C. But when I navigate to CI need view controller B to be dismissed to avoid the stacking.我从视图控制器 A 开始,然后导航到视图控制器 B(用户应该在此视图中选择他们的名字),然后从 BI 导航到 C。但是当我导航到 CI 时需要关闭视图控制器 B以避免堆积。 But I can't find a good way to just remove the current view controller and navigate to a new one.但是我找不到一种好方法来删除当前的视图控制器并导航到一个新的视图控制器。

    func navigateToService(selectedCar: String!){

    if let storyboard = storyboard{
        let vc = storyboard.instantiateViewController(withIdentifier: "BookServiceViewController") as! BookServiceViewController

        self.dismiss(animated: true) //<---

        vc.selectedCar = selectedCar

        self.present(vc, animated: true)
    }
}

I've tried this and a lot more so far.到目前为止,我已经尝试过这个以及更多。 But nothing seem to work in my case.但在我的情况下似乎没有任何效果。 The code I've added in the thread is just closing the view immediately and is not opening a new one.我在线程中添加的代码只是立即关闭视图,而不是打开一个新视图。

So how can I navigate from A -> B -> Dimiss B -> C?那么如何从 A -> B -> Dimiss B -> C 导航?

TEMPORARY EDIT, WILL BE REMOVED临时编辑,将被删除

    func navigateToService(selectedCar: String!){

    self.dismiss(animated: true) {
        if let storyboard = self.storyboard{
           let vc = storyboard.instantiateViewController(withIdentifier: "BookServiceViewController") as! BookServiceViewController


           vc.selectedCar = selectedCar

           self.present(vc, animated: true)
       }
    }

}
self.dismiss(animated: true) {
   # do your job in here
}

present your UIViewController in here but you have to get an instance of the UIViewController which will be presented.在此处展示您的UIViewController ,但您必须获得将展示的UIViewController的实例。

Edit编辑

Describe a protocol描述一个协议

protocol Handler{
    func  handleIt()
}


class AController: UIViewController, Handler {

    func handleIt() {
        // present controller C
        /*
         self.present( C Controller )
         */
    }
...

    func presentFunction(){

        var controller = BController()
        controller.delegate = self

    }

}

Conformance it with this protocol then set it with the present C controller . Conformance此协议,然后使用present C controller设置它。

class BController: UIViewController{

    var delegate: Handler?

    func dismissFunction(){

        self.dismiss(animated: true, completion: nil)

        delegate?.handleIt()

    }
    ...
}

In controller B you have to describe like this.在控制器 B 中,您必须这样描述。 So when you trigger dismiss function call the delegate's handleIt function.因此,当您触发解除函数时,请调用delegate's handleIt函数。 It presents C from A .它从A presents C

I hope it helps you.我希望它能帮助你。

Try this code:-试试这个代码:-

First, your current presented view(B) make push view with this code and after try to present your 'BookServiceViewController' view(C)首先,您当前呈现的视图(B)使用此代码制作推送视图,然后尝试呈现您的“BookServiceViewController”视图(C)

    let nextVC = self.storyboard?.instantiateViewController(withIdentifier: "Your_Current_Presented_View") as! Your_Current_Presented_View

    let nav = UINavigationController(rootViewController: nextVC)
    nav.navigationBar.isHidden = true
    DispatchQueue.main.async {
        self.present(nav, animated: true, completion: nil)
    }

And after present, Call your function在现在之后,调用你的函数

func navigateToService(selectedCar: String!){

if let storyboard = storyboard{
    let vc = storyboard.instantiateViewController(withIdentifier: "BookServiceViewController") as! BookServiceViewController

    self.dismiss(animated: true) //<---

    vc.selectedCar = selectedCar

    self.present(vc, animated: true)
}}

In A:在一个:

func goToB(_ sender: Any) {
        guard let controller = self.storyboard?.instantiateViewController(withIdentifier: "B_ViewController") as? B_ViewController else{return}
        self.present(controller, animated: true, completion: nil)
    }

func proceedToC(selectedCar:String){
        guard let controller = self.storyboard?.instantiateViewController(withIdentifier: "C_ViewController") as? C_ViewController else{return}
        controller.car = selectedCar
        self.present(controller, animated: true, completion: nil)
}

In B:在乙:

func goToC(_ sender: Any) {
        if let presenter = self.presentingViewController, presenter.isKind(of: A_ViewController.self), let vc = presenter as? A_ViewController{
            self.dismiss(animated: false) {
                vc.proceedToC(selectedCar: "Corvette")
            }
        }

1.when you are navigating to B just pass the A controller object like this:- @IBAction func GoToB(_ sender: Any) { let Bcontroller = self.storyboard?.instantiateViewController(withIdentifier: "B") as! 1.当您导航到 B 时,只需像这样传递 A 控制器对象:- @IBAction func GoToB(_ sender: Any) { let Bcontroller = self.storyboard?.instantiateViewController(withIdentifier: "B") as! B Bcontroller.Aobje = self self.navigationController?.pushViewController(Bcontroller, animated: true) } B Bcontroller.Aobje = self self.navigationController?.pushViewController(Bcontroller, animation: true) }

2.the time of navigation from B to C use A controller object for navigation like given below. 2.从 B 到 C 的导航时间使用 A 控制器对象进行导航,如下所示。

var Aobje = A()

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

@IBAction func BtoC(_ sender: Any) {
    let Ccontroller = self.storyboard?.instantiateViewController(withIdentifier: "C") as! C
         Aobje.navigationController?.pushViewController(Ccontroller, animated: true)
    self.removeFromParent()
}

Multiple dismissal at same time多人同时解雇

You should dismiss the controller who presents this one to dismiss both together in this case:在这种情况下,您应该解雇提出此要求的控制者以同时解雇两者:

self.presentingViewController!.dismiss(animated: true) // `!` is to makeing sure it's not crashing.

Demo:演示:

Use this simple code to demo:使用这个简单的代码来演示:

class ViewController: UIViewController {
    @IBAction func present() {
        let destination = storyboard!.instantiateInitialViewController()!
        if presentingViewController != nil {
            // You are not in the A
            if presentingViewController?.presentingViewController != nil {
                // You are in the C
                presentingViewController?.presentingViewController?.dismiss(animated: true)
                return
            } else {
                // You are in the B
                destination.modalPresentationStyle = .currentContext
            }
        }
        present(destination, animated: true, completion: nil)
    }
}

Usage:用法:

  1. Create a single view application创建单视图应用程序
  2. Drag a button into the view controller将按钮拖入视图控制器
  3. Replace the ViewController class with the provided code用提供的代码替换ViewController
  4. Connect the @IBAction连接@IBAction
  5. Run it to see the result.运行它以查看结果。

Change the root of the window entirely:完全改变窗口的根:

If you want to get rid of the entire stack and act like you just start the app starting from the C view controller, you can just set the root of the window to C .如果您想摆脱整个堆栈并表现得像从C视图控制器启动应用程序一样,您只需将窗口的根设置C

view.window!.rootViewController = destination

This is like you set the initialViewController arrow on the destination at first place.这就像您首先在目的地上设置了 initialViewController 箭头。

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

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM