UIViewControllerAnimatedTransitioning вызывает необычную прокрутку tableViewController, когда изображение представлено и отклонено

Я использую анимированный переход для отображения изображений в своем приложении чата. Я использую следующий класс аниматоров для перехода.

В основном переход работает хорошо и очень плавно. Во всех случаях переход к 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
}

И код в таблице ViewController:

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 ответов

Другие вопросы по тегам