[英]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.