【问题标题】:When is the destination view controller initialized during a segue?在 segue 期间何时初始化目标视图控制器?
【发布时间】:2017-01-20 18:31:26
【问题描述】:

我正在尝试编写一个协议和一个自定义 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 变量为零,但控制器本身不是。这是一个糟糕的设计模式,还是我只是缺少一些简单的东西?

【问题讨论】:

    标签: ios swift uiviewcontroller segue uistoryboardsegue


    【解决方案1】:

    误诊问题...目标控制器已加载,但我忘记将目标控制器的视图添加到 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)
                        }
                    }
                }
            }
        }
    }   
    

    【讨论】:

      【解决方案2】:

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

      视图控制器的view 属性是延迟加载的,并且此时会构建并连接出口。这就是为什么viewDidLoad() 是一个东西。

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2019-10-13
        • 1970-01-01
        • 1970-01-01
        • 2014-05-16
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多