如何从"过流内容"视图控制器?

时间:2018-01-10 10:52:13

标签: ios swift uiviewcontroller swift4

我的应用程序中有两个ViewController,ViewController和ViewController2

在ViewController中,按钮组Present Modally segue to "ViewController2"

ViewController覆盖viewWillAppear

override func viewWillAppear(_ animated: Bool) {
    super.viewDidAppear(animated)
    print("will appear")
}

在ViewController2中,返回一个按钮

@IBAction func close(_ sender: Any) {
    self.dismiss(animated: true, completion: nil)
}

现在它仍然可以触发viewWillAppear然后我从ViewController2返回ViewController

如果我将ViewController2的演示文稿从Full Screen更改为Over Current Context,则viewWillAppear将不会被触发

返回后如何触发某些代码?

4 个答案:

答案 0 :(得分:2)

你可以在不放弃故事板segue的情况下完成它,但你必须在ViewCOntroller2中设置will / did消失处理程序:

class ViewController: UIViewController {
    ...
    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        if let destination = segue.destination as? ViewController2 {
            (segue.destination as? ViewController2).onViewWillDisappear = {
                //Your code
            }
        }
    }
}

class ViewController2: UIViewController {
    var onViewWillDisappear: (()->())?

    override func viewWillDisappear(_ animated: Bool) {
        super.viewWillDisappear(animated)
        onViewWillDisappear?()
    }
    ...
}

答案 1 :(得分:1)

有几种方法可以处理此操作。这是我过去常用的一个。

// ViewController1
class ViewController1: UIViewController {


   @IBAction func presentOverCurrentContext(button: Button) {
        let vc2 = // instantiate ViewController2
        vc2.modalPresentationStyle = .overFullScreen
        vc2.presentingVC = self   // use this variable 'presentingVC' to connect both view controllers
        self.present(vc2, animated: true)
   }

}


// ViewController2
class ViewController2: UIViewController {

   var presentingVC: UIViewController?  // use this variable to connect both view controllers
   @IBAction func close(button: Button) {

        // handle operation here
        presentingVC?.viewWillAppear(true)

        self.dismiss(animated: true, completion: { 

            // or here
            // presentingVC?.viewWillAppear(true)
        })
   }

}

您也可以使用自己的方法重新加载view / viewcontroller,但viewWillAppear是所有视图控制器的常用方法(作为超类生命周期的一部分),因此您可能不需要指定自定义类型查看presentingVC的控制器

答案 2 :(得分:1)

虽然到目前为止提供的答案确实有效但我认为使用协议和委托来表明如何做到这一点是一个好主意,这是一个干净的实现,然后还允许添加更多功能最小的努力。

所以建立这样的协议:

protocol SecondViewControllerProtocol: class {
    func closed(controller: SecondViewController)
}

像这样设置第二个视图控制器:

class SecondViewController {
    public weak var delegate: SecondViewControllerProtocol?

    @IBAction func close(_ sender: Any) {
        self.dismiss(animated: true, completion: nil)
        self.delegate?.close(controller: self)
    }
}

像这样设置第一个视图控制器:

class FirstViewController: SecondViewControllerProtocol {
    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        if segue.identifier == "SecondViewControllerID",
            let secondViewController = segue.destination as? SecondViewController {
            secondViewController.delegate = self
        }
    }

    func closed(controller: SecondViewController) {
    // Any code you want to execute when the second view controller is dismissed
    }
}

像这样实现它可以完成原始请求,并允许在协议中放入额外的方法,以便FirstViewController可以响应SecondViewController中的其他操作。

注意:

您可能希望将委托方法调用移动到dismiss处理程序的闭包中,以便您知道在SecondViewController实际消失之前不会调用该方法(如果您尝试呈现另一个失败的视图)。如果是这样的话,你可以这样做:

@IBAction func close(_ sender: Any) {
    self.dismiss(animated: true) {
        self.delegate?.close(controller: self)
    }
}

事实上你可以有一个遗嘱和方法,并按照这样的方式调用它们:

@IBAction func close(_ sender: Any) {
    self.delegate?.willClose(controller: self)
    self.dismiss(animated: true) {
        self.delegate?.didClose(controller: self)
    }
}

这将允许您在第二个控制器动画播放时立即执行某些操作,然后知道它何时实际消失。

答案 3 :(得分:0)

处理此场景以使用回调处理程序的最佳/干净方式。

示例代码

 x(n+1,:,:) = x(n+1,:,:) + reshape([cos(theta(:)) sin(theta(:))].',1,2,M);