【问题标题】:Custom VC Transition not Dismissing Properly自定义 VC 转换未正确关闭
【发布时间】: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。

标签: ios swift


【解决方案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)
            }
        }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-12-23
      • 2020-06-16
      相关资源
      最近更新 更多