UIViewControllerAnimatedTransitioning在显示和关闭图像时会导致tableViewController异常滚动

时间:2018-06-20 03:47:36

标签: ios swift xcode animation uiviewanimationtransition

我正在使用动画过渡在聊天应用程序中显示图像。我将以下动画师类用作过渡对象。

大多数情况下,过渡效果良好且非常顺利。在任何情况下,都非常适合过渡到imageViewController以显示图像。但是,有时候向后过渡时,tableView contentOffset发生了变化,并且图像不再过渡回正确的位置。

我想要的是使用.overCurrentContext进行此过渡,但是当我尝试返回动画可以正常工作,但随后删除原始tableView时,屏幕变黑了。即使我将变量self.definesPresentationContext设置为true。

尝试了几天后,我放弃了overCurrentContext,所以现在我只是想弄清为什么tableView有时会更改偏移量以及如何解决该偏移量。或者,如果有更好的方法来实现过渡,以在另一个viewController中显示图像。

import UIKit

class Animator: NSObject, UIViewControllerAnimatedTransitioning {


    private var image: UIImage?
    private var fromDelegate: ImageTransitionProtocol?
    private var toDelegate: ImageTransitionProtocol?

    // MARK: Setup Methods

    func setupImageTransition(image: UIImage, fromDelegate: ImageTransitionProtocol, toDelegate: ImageTransitionProtocol) {
        self.image = image
        self.fromDelegate = fromDelegate
        self.toDelegate = toDelegate


    }

    // MARK: UIViewControllerAnimatedTransitioning

    // 1: Set animation speed
    func transitionDuration(using transitionContext: UIViewControllerContextTransitioning?) -> TimeInterval {
        return 0.6
    }


    func animateTransition(using transitionContext: UIViewControllerContextTransitioning) {

        let containerView = transitionContext.containerView
        // 2: Get view controllers involved
        let fromVC = transitionContext.viewController(forKey: UITransitionContextViewControllerKey.from)!
        let toVC = transitionContext.viewController(forKey: UITransitionContextViewControllerKey.to)!

        // 3: Set the destination view controllers frame
        //toVC.view.frame = fromVC.view.frame

        toVC.view.frame = transitionContext.finalFrame(for: toVC)

        // 4: Create transition image view
        let imageView = UIImageView(image: image)
        imageView.contentMode = .scaleAspectFill
        imageView.frame = (fromDelegate == nil) ? CGRect() : fromDelegate!.imageWindowFrame()
        imageView.clipsToBounds = true

        containerView.addSubview(imageView)

        // 5: Create from screen snapshot

        fromDelegate!.transitionSetup()
        toDelegate!.transitionSetup()
        let fromSnapshot = fromVC.view.snapshotView(afterScreenUpdates: true)!
        fromSnapshot.frame = fromVC.view.frame
        containerView.addSubview(fromSnapshot)

        // 6: Create to screen snapshot
        let toSnapshot = toVC.view.snapshotView(afterScreenUpdates: true)!
        toSnapshot.frame = fromVC.view.frame
        containerView.addSubview(toSnapshot)
        toSnapshot.alpha = 0

        // 7: Bring the image view to the front and get the final frame
        containerView.bringSubview(toFront: imageView)
        let toFrame = (self.toDelegate == nil) ? CGRect() : self.toDelegate!.imageWindowFrame()


        // 8: Animate change
        UIView.animate(withDuration: transitionDuration(using: transitionContext), delay: 0, usingSpringWithDamping: 0.7, initialSpringVelocity: 0.8, options: .curveEaseOut, animations: {
            toSnapshot.alpha = 1
            imageView.frame = toFrame
        }, completion:{ [weak self] (finished) in
            self?.toDelegate!.transitionCleanup()
            self?.fromDelegate!.transitionCleanup()
            // 9: Remove transition views
            imageView.removeFromSuperview()
            fromSnapshot.removeFromSuperview()
            toSnapshot.removeFromSuperview()

            // 10: Complete transition
            if !transitionContext.transitionWasCancelled {
                containerView.addSubview(toVC.view)
            }
            transitionContext.completeTransition(!transitionContext.transitionWasCancelled)
        })
    }

}

protocol ImageTransitionProtocol {
    func transitionSetup()
    func transitionCleanup()
    func imageWindowFrame() -> CGRect
}

以及tableViewController中的代码:

func animationController(forPresented presented: UIViewController, presenting: UIViewController, source: UIViewController) -> UIViewControllerAnimatedTransitioning? {
    let imagePresentationViewController = (presented as! UINavigationController).topViewController as! ImagePresentationViewController
    self.transition.setupImageTransition( image: pickedImageForTransition!,
                                          fromDelegate: self,
                                          toDelegate: imagePresentationViewController)
    return transition
}

func animationController(forDismissed dismissed: UIViewController) -> UIViewControllerAnimatedTransitioning? {
    let imagePresentationViewController = (dismissed as! UINavigationController).topViewController as! ImagePresentationViewController
    transition.setupImageTransition( image: pickedImageForTransition!,
                                     fromDelegate: imagePresentationViewController,
                                     toDelegate: self)
    return transition
}

0 个答案:

没有答案