繁体   English   中英

目标视图控制器何时在 segue 期间初始化?

[英]When is the destination view controller initialized during a segue?

我正在尝试编写一个协议和一个自定义 UIStoryboardSegue 类,这将允许我在我的 UIViewControllers 中轻松实现自定义转换:

public protocol TransitionController
{
    var transitionDurationIn:  CFTimeInterval { get }
    var transitionDurationOut: CFTimeInterval { get }
    func prepareTransitionIn()
    func prepareTransitionOut()
    func performTransitionIn(finished: @escaping () -> Void)
    func performTransitionOut(finished: @escaping () -> Void)
}

class JFTransitionControllerSegue: UIStoryboardSegue {
    override func perform() {
        let defaultTransitionDuration : CFTimeInterval = 1.5

        if let dvc = self.destination as? TransitionController {
            dvc.prepareTransitionIn()
        }
        else {
            // Default transition
            self.destination.view.alpha = 0
        }
        if let svc = self.source as? TransitionController {
            svc.prepareTransitionOut()
            svc.performTransitionOut(){ () in
                if let dvc = self.destination as? TransitionController {
                    dvc.performTransitionIn(){ () in
                        self.source.present(self.destination, animated: false, completion: nil)
                    }
                }
                else {
                    // Default transition for the destination controller
                    UIView.animate(withDuration: defaultTransitionDuration, animations: {
                        self.destination.view.alpha = 1
                    }) { (Finished) in
                        self.source.present(self.destination, animated: false, completion: nil)
                    }
                }
            }
        }
        else
        {
            // Default transition for the source controller
            UIView.animate(withDuration: defaultTransitionDuration, animations: {
                self.source.view.alpha = 0
            }) { (Finished) in
                if let dvc = self.destination as? TransitionController {
                    dvc.performTransitionIn(){ () in
                        self.source.present(self.destination, animated: false, completion: nil)
                    }
                }
                else {
                    // Default transition for the destination controller
                    UIView.animate(withDuration: defaultTransitionDuration, animations: {
                        self.destination.view.alpha = 1
                    }) { (Finished) in
                        self.source.present(self.destination, animated: false, completion: nil)
                    }
                }
            }
        }
    }
}

class TestController: UIViewController, TransitionController {
    @IBOutlet weak var form_username: UITextField!

    // MARK: - TransitionController Protocol

    var transitionDurationIn  : CFTimeInterval {return 1.0}
    var transitionDurationOut : CFTimeInterval {return 1.0}

    func prepareTransitionIn()
    {
        //self.view.alpha = 0 // no fade in if you uncomment
        form_username.alpha = 0 // nil
    }
    func prepareTransitionOut()
    {
        self.view.alpha = 1 // works
    }
    func performTransitionIn(finished: @escaping () -> Void)
    {
        UIView.animate(withDuration: self.transitionDurationIn, animations: {
            //self.view.alpha = 1 // no fade in if you uncomment
            self.form_username.alpha = 1 // nil, crashes
        }) { (Finished) in
            finished()
        }
    }
    func performTransitionOut(finished: @escaping () -> Void)
    {
        UIView.animate(withDuration: self.transitionDurationOut, animations: {
            self.view.alpha = 0 // fades out correctly
        }) { (Finished) in
            finished()
        }
    }
}

基本上,您只需在您想要的任何 UIViewController 中实现该协议,然后创建 JFTransitionControllerSegue 类的 segue。 performTransitionIn函数中,你可以做一些类似UIView.animate事情并改变 alpha 或任何你喜欢的东西。 我遇到的问题是目标转场只是弹出而不是正确过渡。 从我在调试时可以看出它没有完全初始化 - IBOutlet 变量为零,但控制器本身不是。 这是一个糟糕的设计模式,还是我只是缺少一些简单的东西?

被初始化的视图控制器是一个事件。 正在加载的视图是另一个视图。

视图控制器的view属性被延迟加载,并且出口在此时构建和连接。 这就是viewDidLoad()是一个东西的原因。

如果你想让视图为你准备好,你可以先在视图控制器上调用loadViewIfNeeded()

误诊了问题...目标控制器已加载,但我忘记将目标控制器的视图添加到Segue类中的窗口中:

class JFTransitionControllerSegue: UIStoryboardSegue {
    override func perform() {
        let defaultTransitionDuration : CFTimeInterval = 1.5

        if let dvc = self.destination as? TransitionController {
            dvc.prepareTransitionIn()
        }
        else {
            // Default transition
            self.destination.view.alpha = 0
        }
        if let svc = self.source as? TransitionController {
            svc.prepareTransitionOut()
            svc.performTransitionOut(){ () in

                UIApplication.shared.keyWindow?.insertSubview(self.destination.view, aboveSubview: self.source.view)
                if let dvc = self.destination as? TransitionController {
                    dvc.performTransitionIn(){ () in
                        self.source.present(self.destination, animated: false, completion: nil)
                    }
                }
                else {
                    // Default transition for the destination controller
                    UIView.animate(withDuration: defaultTransitionDuration, animations: {
                        self.destination.view.alpha = 1
                    }) { (Finished) in
                        self.source.present(self.destination, animated: false, completion: nil)
                    }
                }
            }
        }
        else
        {
            // Default transition for the source controller
            UIView.animate(withDuration: defaultTransitionDuration, animations: {
                self.source.view.alpha = 0
            }) { (Finished) in
                UIApplication.shared.keyWindow?.insertSubview(self.destination.view, aboveSubview: self.source.view)
                if let dvc = self.destination as? TransitionController {
                    dvc.performTransitionIn(){ () in
                        self.source.present(self.destination, animated: false, completion: nil)
                    }
                }
                else {
                    // Default transition for the destination controller
                    UIView.animate(withDuration: defaultTransitionDuration, animations: {
                        self.destination.view.alpha = 1
                    }) { (Finished) in
                        self.source.present(self.destination, animated: false, completion: nil)
                    }
                }
            }
        }
    }
}   

暂无
暂无

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

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