【问题标题】:CGAffineTransform.identity doesn't reset transform correctly after device rotation设备旋转后 CGAffineTransform.identity 无法正确重置变换
【发布时间】:2019-02-09 07:57:33
【问题描述】:

我正在做一个自定义转换,如果在呈现动画之后,设备将被旋转,然后destinationVC 将被关闭,originVC 转换不正确(不完成屏幕)。如果没有设备旋转,一切正常。有没有人可以帮帮我?

这是我展示和关闭动画的代码:

func animateTransition(using transitionContext: UIViewControllerContextTransitioning) {
        guard let originViewController = transitionContext.viewController(forKey: .from),
            let destinationViewController = transitionContext.viewController(forKey: .to) else { return }

        destinationViewController.view.transform = CGAffineTransform(translationX: 0, y: destinationViewController.view.frame.height)
        let duration = transitionDuration(using: transitionContext)

        UIView.animate(withDuration: duration, animations: {
            destinationViewController.view.transform = CGAffineTransform(translationX: 0, y: 0)
            originViewController.view.transform = originViewController.view.transform.scaledBy(x: 0.95, y: 0.95)
            originViewController.view.layer.cornerRadius = 8.0
        }, completion: { completed in            
            transitionContext.completeTransition(completed)
        })
    }

func animateTransition(using transitionContext: UIViewControllerContextTransitioning) {
        guard let originViewController = transitionContext.viewController(forKey: .from),
            let destinationViewController = transitionContext.viewController(forKey: .to) else { return }

        let duration = transitionDuration(using: transitionContext)

        UIView.animate(withDuration: duration, animations: {
            originViewController.view.transform = CGAffineTransform(translationX: 0, y: destinationViewController.view.frame.height)
            destinationViewController.view.transform = CGAffineTransform.identity
            destinationViewController.view.layer.cornerRadius = 0.0
        }, completion: { completed in
            transitionContext.completeTransition(!transitionContext.transitionWasCancelled)
        })
    }

屏幕: 之前的动画 现在动画之后 设备旋转后 关闭动画后

编辑: 当我添加 destinationViewController.view.frame = transitionContext.finalFrame(for: destinationViewController) 以关闭动画时,一切似乎都正常,但我不知道这是否正确

【问题讨论】:

  • 我用UIViewControllerTransitioningDelegate 扩展了我的SecondViewController 并实现:animationController(forPresented...animationController(forDismissed dismissed:...

标签: ios swift uikit cgaffinetransform cgaffinetransformscale


【解决方案1】:

在 ViewC1 中添加一个带有前导、顶部、底部、尾随约束的子视图。 工作完整代码

class ViewC1: UIViewController {

    @IBAction func presentNow(_ sender: Any) {
        let viewc = storyboard!.instantiateViewController(withIdentifier: "ViewC2") as! ViewC2
        viewc.transitioningDelegate = viewc
        viewc.modalPresentationStyle = .overCurrentContext
        present(viewc, animated: true, completion: nil)
    }

}

class ViewC2: UIViewController {

    let pres = PresentAnimator()
    let diss = DismissAnimator()

    @IBAction func dissmisNow(_ sender: Any) {
        dismiss(animated: true, completion: nil)
    }
}

extension ViewC2: UIViewControllerTransitioningDelegate {
    func animationController(forPresented presented: UIViewController, presenting: UIViewController, source: UIViewController) -> UIViewControllerAnimatedTransitioning? {
        return pres
    }

    func animationController(forDismissed dismissed: UIViewController) -> UIViewControllerAnimatedTransitioning? {
        return diss
    }
}

class PresentAnimator: NSObject, UIViewControllerAnimatedTransitioning {

    func transitionDuration(using transitionContext: UIViewControllerContextTransitioning?) -> TimeInterval {
        return 1.0
    }

    func animateTransition(using transitionContext: UIViewControllerContextTransitioning) {
        guard let originViewController = transitionContext.viewController(forKey: .from),
            let destinationViewController = transitionContext.viewController(forKey: .to) else { return }

        transitionContext.containerView.addSubview(destinationViewController.view)
        destinationViewController.view.frame = transitionContext.containerView.bounds

        let originView = originViewController.view.subviews.first

        destinationViewController.view.transform = CGAffineTransform(translationX: 0, y: destinationViewController.view.frame.height)
        let duration = transitionDuration(using: transitionContext)

        UIView.animate(withDuration: duration, animations: {
            destinationViewController.view.transform = CGAffineTransform(translationX: 0, y: 0)
            originView?.transform = CGAffineTransform(scaleX: 0.95, y: 0.95)
            originView?.layer.cornerRadius = 8.0
        }, completion: { completed in
            transitionContext.completeTransition(completed)
        })
    }
}

class DismissAnimator: NSObject, UIViewControllerAnimatedTransitioning {

    func transitionDuration(using transitionContext: UIViewControllerContextTransitioning?) -> TimeInterval {
        return 1.0
    }

    func animateTransition(using transitionContext: UIViewControllerContextTransitioning) {
        guard let originViewController = transitionContext.viewController(forKey: .from),
            let destinationViewController = transitionContext.viewController(forKey: .to) else { return }

        let originView = destinationViewController.view.subviews.first
        let duration = transitionDuration(using: transitionContext)

        UIView.animate(withDuration: duration, animations: {
            originViewController.view.transform = CGAffineTransform(translationX: 0, y: destinationViewController.view.frame.height)
            originView?.transform = CGAffineTransform.identity
            originView?.layer.cornerRadius = 0.0
        }, completion: { completed in
            transitionContext.completeTransition(!transitionContext.transitionWasCancelled)
        })
    }
}

更新: 或者如果你不想使用view.subviews.first,你可以覆盖 willRotate 和 didRotate

var prevTrans: CGAffineTransform?
override func willRotate(to toInterfaceOrientation: UIInterfaceOrientation, duration: TimeInterval) {
    prevTrans = view.transform
    view.transform = CGAffineTransform.identity
}

override func didRotate(from fromInterfaceOrientation: UIInterfaceOrientation) {
    if let prevTrans = prevTrans {
        view.transform = prevTrans
    }
}

【讨论】:

  • 我将此添加到我的应用程序代码中,但缩放动画不起作用
猜你喜欢
  • 2022-08-15
  • 2011-11-09
  • 2011-07-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多