2016-09-13 24 views
1

私は私は簡単に私のUIViewControllersでカスタムの移行を実施することを可能にするプロトコルとカスタムUIStoryboardSegueクラスを記述しようとしています:segueの間に宛先ビューコントローラが初期化されるのはいつですか?

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のような何かを行い、アルファまたは好きなものを変更することができます。私が抱えている問題は、適切に移行するのではなく、宛先セグが単にポップアップすることです。デバッグ中に私が知ることは、完全に初期化されていないからです.IBOutlet変数はnilですが、コントローラ自体はありません。これは悪いデザインパターンですか、それとも単純なものが欠けていますか?

答えて

1

初期化されているビューコントローラは1つのイベントです。ロードされているビューは別のビューです。

ビューコントローラのプロパティが遅延ロードされ、その時点でアウトレットが構築され、接続されます。だからこそviewDidLoad()が事です。

ビューを準備する場合は、最初にビューコントローラでloadViewIfNeeded()と呼ぶことができます。問題を誤診

0

...先のコントローラがロードされましたが、私はセグエクラスのウィンドウに移動先のコントローラのビューを追加するには忘れていた:

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) 
        } 
       } 
      } 
     } 
    } 
} 
関連する問題