modalPresentationStyle .overCurrentContext в пользовательской анимации containerView возвращается к черному экрану

У меня есть tableViewController в containerView другого viewController.

Когда изображение нажато, происходит настраиваемый переход к другому viewController для просмотра изображения. Переход работает хорошо.

Когда происходит пользовательский переход, хотя viewWillDisappear вызывается для tableViewController контейнера, а затем снова viewWillAppear, когда представленный viewController отклоняется (снова с переходом).

Это иногда вызывает необычную прокрутку в tableView.

Я хотел бы представить imageViewer с переходом, но overCurrentContext.

Я пробовал то, что люди предлагают, а именно следующее:

self.definesPresentationContext = true
vc.modalPresentationStyle = .overCurrentContext
vc.transitioningDelegate = self
self.present(vc, animated: true, completion: nil)

К сожалению, это не работает, и когда imageViewController отклоняется, первоначально переход назад выполняется правильно, и tableViewController можно увидеть. Но как только переход завершен, изображение становится черным.

Я думаю, это может быть связано с тем, что я использую containerView. Но не уверен и не уверен, как это решить.

Это метод аниматора, который я использую:

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.4
}

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

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

И это в представленном viewController:

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

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

person alionthego    schedule 17.06.2018    source источник
comment
Вы пробовали .overFullScreen?   -  person Sina KH    schedule 17.06.2018
comment
это не работает.   -  person alionthego    schedule 17.06.2018
comment
Это может быть не проблема, но обратите внимание, что каждый раз, когда вы говорите что-то вроде fromVC.view, это неправильно. Вы должны получить представление, используя view(forKey:).   -  person matt    schedule 17.06.2018
comment
Также я могу что-то упустить, но где ваши звонки initialFrame и finalFrane? Вы не вольны придумывать кадры, вы должны получать их из контекста.   -  person matt    schedule 17.06.2018
comment
И я не вижу ни одного кода, где бы вы действительно выполняли свои обязанности по переносу представления контроллера для просмотра в контекст и так далее.   -  person matt    schedule 17.06.2018
comment
отредактировано, чтобы показать инициализацию   -  person alionthego    schedule 17.06.2018
comment
это было из онлайн-учебника, который я сделал некоторое время назад. Это очень хорошо работает для анимированного перехода. просто когда я пытаюсь использовать overCurrentContext, он возвращается к черному экрану   -  person alionthego    schedule 17.06.2018
comment
На нем есть видео WWDC, оно может помочь developer.apple.com/videos/ играть/wwdc2014/228   -  person user1046037    schedule 17.06.2018


Ответы (1)


Была такая же проблема, вам просто нужно удалить представление контейнера из func animateTransition(using transitionContext: UIViewControllerContextTransitioning)

person StaticV0id    schedule 12.03.2019