自定义 VC 转换未正确关闭
Posted
技术标签:
【中文标题】自定义 VC 转换未正确关闭【英文标题】:Custom VC Transition not Dismissing Properly 【发布时间】:2019-11-22 07:11:42 【问题描述】:我正在尝试使用自定义转换在 VC 中重新创建库存 UIAlertAction。我目前的演示工作完美(backgroundView
淡入,“通知”VC 从底部滑出)。我面临的问题是当我解雇 VC 时,backgroundView
不会淡出。就好像它完全绕过了我的动画块。一旦completeTransition
被调用,backgroundView
就会完全消失。怎么了?
class AnimationController: NSObject
let backgroundView = UIView()
extension AnimationController: UIViewControllerAnimatedTransitioning
func animateTransition(using transitionContext: UIViewControllerContextTransitioning)
let containerView = transitionContext.containerView
guard let toViewController = transitionContext.viewController(forKey: .to),
let fromViewController = transitionContext.viewController(forKey: .from) else
transitionContext.completeTransition(false)
return
switch animationType
case .present:
backgroundView.frame = CGRect(x: 0, y: 0, width: toViewController.view.frame.width, height: fromViewController.view.frame.height)
backgroundView.backgroundColor = UIColor(red: 0, green: 0, blue: 0, alpha: 0.4)
backgroundView.alpha = 0
containerView.addSubview(backgroundView)
let viewToAnimate = toViewController.view!
containerView.addSubview(viewToAnimate)
toViewController.view.clipsToBounds = true
viewToAnimate.frame = CGRect(x: 0, y: viewToAnimate.frame.maxY, width: viewToAnimate.frame.width, height: viewToAnimate.frame.height)
let duration = transitionDuration(using: transitionContext)
UIView.animate(withDuration: duration, delay: 0, usingSpringWithDamping: 0.80, initialSpringVelocity: 0.1, options: .curveEaseInOut, animations:
self.backgroundView.alpha = 1.0
viewToAnimate.transform = CGAffineTransform(translationX: 0, y: -viewToAnimate.frame.height)
) _ in
transitionContext.completeTransition(true)
case .dismiss:
containerView.addSubview(fromViewController.view!)
let testView = fromViewController.view!
backgroundView.frame = CGRect(x: 0, y: 0, width: testView.frame.width, height: testView.frame.height)
backgroundView.backgroundColor = UIColor(red: 1, green: 0, blue: 0, alpha: 1)
let duration = transitionDuration(using: transitionContext)
UIView.animate(withDuration: duration, delay: 0, usingSpringWithDamping: 0.80, initialSpringVelocity: 0.1, options: .curveEaseInOut, animations:
self.backgroundView.alpha = 0.0
testView.transform = CGAffineTransform(translationX: 0, y: testView.frame.height)
print("backgroundView Doesn't fade out")
) _ in
print("backgroundView disappears here")
transitionContext.completeTransition(true)
【问题讨论】:
您是否在新的*** VC 中注册了过渡委托? @SanthoshSKashyap 它调用 animateTransition 函数,所以我认为这不是问题...... 看看一个有效的例子会有帮助吗? github.com/mattneub/custom-alert-view-ios7 @matt 谢谢你,我正在尝试将视图动画化为 2 个单独的元素(背景 + 视图)。此示例将其动画化为单个元素... 只是预感,你试过在主线程上调度它吗?接下来要尝试的是使用图层不透明度而不是视图 alpha。 【参考方案1】:你可以尝试这样展示
//where DevolucionVC is you ViewController
if let controller = DevolucionVC() as? DevolucionVC
if let window = self.window, let rootViewController = window.rootViewController
var currentController = rootViewController
while let presentedController = currentController.presentedViewController
currentController = presentedController
currentController.present(controller, animated: true, completion: nil)
您可以稍后通过简单地使用来关闭它
dismiss(animated: true, completion: nil)
【讨论】:
【参考方案2】:试试这个
暂时替换此代码
backgroundView.frame = CGRect(x: 0, y: 0, width: toViewController.view.frame.width, height: fromViewController.view.frame.height)
backgroundView.backgroundColor = UIColor(red: 0, green: 0, blue: 0, alpha: 0.4)
backgroundView.alpha = 0
containerView.addSubview(backgroundView)
let transition = CATransition()
transition.duration = 0.5
transition.type = CATransitionType.moveIn
transition.subtype = CATransitionSubtype.fromTop
containerView.layer.add(transition, forKey: kCATransition)
对于 Dismiss 替换此代码
containerView.addSubview(fromViewController.view!)
let transition = CATransition()
transition.duration = 0.5
transition.type = CATransitionType.fade
containerView.layer.add(transition, forKey: kCATransition)
backgroundView.frame = CGRect(x: 0, y: 0, width: testView.frame.width, height: testView.frame.height)
backgroundView.backgroundColor = UIColor(red: 1, green: 0, blue: 0, alpha: 1)
self.backgroundView.alpha = 0.0
【讨论】:
我刚刚添加了这段代码,目前它根本不会淡入背景视图。我错过了什么吗?【参考方案3】:您的问题是您正在处理 AnimationController
的两个单独实例,因此是 backgroundView
的两个单独实例。一个实例为演示而实例化,而另一个实例为解雇而实例化。请注意,在您的 case .present:
块中,您正在调用 containerView.addSubview(backgroundView)
,但您在 case .dismiss:
块中没有这样做。因此,case .dismiss:
块中的 backgroundView
实例甚至不是视图层次结构的一部分。
您需要做的是在您的第一个动画完成块中调用self.backgroundView.removeFromSuperview()
。然后在您的case .dismiss:
中,您需要再次调用containerView.addSubview(backgroundView)
。
试试这个...
switch animationType
case .present:
// ...
containerView.addSubview(backgroundView)
// ...
UIView.animate(withDuration: duration, delay: 0, usingSpringWithDamping: 0.80, initialSpringVelocity: 0.1, options: .curveEaseInOut, animations:
self.backgroundView.alpha = 1.0
viewToAnimate.transform = CGAffineTransform(translationX: 0, y: -viewToAnimate.frame.height)
) _ in
self.backgroundView.removeFromSuperview()
transitionContext.completeTransition(true)
case .dismiss:
// ...
containerView.addSubview(backgroundView)
containerView.addSubview(fromViewController.view!)
// ...
UIView.animate(withDuration: duration, delay: 0, usingSpringWithDamping: 0.80, initialSpringVelocity: 0.1, options: .curveEaseInOut, animations:
self.backgroundView.alpha = 0.0
testView.transform = CGAffineTransform(translationX: 0, y: testView.frame.height)
print("backgroundView Doesn't fade out")
) _ in
print("backgroundView disappears here")
transitionContext.completeTransition(true)
【讨论】:
以上是关于自定义 VC 转换未正确关闭的主要内容,如果未能解决你的问题,请参考以下文章