设备旋转后,CGAffineTransform.identity无法正确重置转换

时间:2019-02-09 07:57:33

标签: ios swift uikit cgaffinetransform cgaffinetransformscale

我正在执行自定义过渡,如果在呈现当前动画之后,设备将旋转,然后将关闭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)
        })
    }

屏幕: 在当前动画之前 Before present animation 当前动画之后 After present animation 设备旋转后 After device rotation 解雇动画后 After dismiss animation

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

1 个答案:

答案 0 :(得分:0)

在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)
        })
    }
}

enter image description here

更新: 或者如果您不想使用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
    }
}