animateTransition 不再适用于 iOS 13 中模态呈现的 viewController

Posted

技术标签:

【中文标题】animateTransition 不再适用于 iOS 13 中模态呈现的 viewController【英文标题】:animateTransition no longer working on modally presented viewController in iOS 13 【发布时间】:2019-10-05 13:20:04 【问题描述】:

当用户在 tableViewController 的单元格中选择 imageView 到显示放大图像的焦点视图时,我一直在我的自定义 Animator 类中使用以下方法进行转换。 imageView 从它在 tableView 中的框架很好地动画到全屏,然后在我关闭它时返回。

这在 ios 13 之前工作得很好。但是现在当我在模态呈现的 tableViewController 上使用这个动画过渡时,焦点视图的动画效果很好,但是当我关闭焦点视图以动画回 tableViewController 时,tableViewController 是不再存在。它只显示模态呈现的 tableViewController 下方的灰色 viewController。我知道新的 modalPresentation 默认样式是 pageSheet 但不确定为什么动画之前的顶视图控制器会消失?

对于非模态显示的视图控制器,动画仍然可以正常工作。

想知道这是一个错误还是有人找到了解决方案?

这是我的 animateTransition 函数:

func animateTransition(using transitionContext: UIViewControllerContextTransitioning) 
    // define variable to keep track of whether transitioning from or to
    var presentingImage = false

    // define containerView
    let containerView = transitionContext.containerView

    // get view controllers
    let fromVC = transitionContext.viewController(forKey: UITransitionContextViewControllerKey.from)!
    let toVC = transitionContext.viewController(forKey: UITransitionContextViewControllerKey.to)!

    // set the destination view controllers frame
    toVC.view.frame = fromVC.view.frame

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

    // add imageView to containerView
    containerView.addSubview(imageView)

    // create from screen snapshot
    fromDelegate!.transitionSetup(presentingImage: presentingImage)
    toDelegate!.transitionSetup(presentingImage: presentingImage)
    let fromSnapshot = fromVC.view.snapshotView(afterScreenUpdates: true)!
    fromSnapshot.frame = fromVC.view.frame
    containerView.addSubview(fromSnapshot)

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

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

    // animate change
    UIView.animate(withDuration: transitionDuration(using: transitionContext), delay: 0, usingSpringWithDamping: 0.7, initialSpringVelocity: 0.8, options: .curveEaseOut, animations: 

        // set toSnapshot alpha to 1
        toSnapshot.alpha = 1

        // set imageView frame to toFrame
        imageView.frame = toFrame

    , completion: (finished) in

        // call transition cleanup for to and from delegate
        self.toDelegate!.transitionCleanup(presentingImage: presentingImage)
        self.fromDelegate!.transitionCleanup(presentingImage: presentingImage)

        // remove transition views
        imageView.removeFromSuperview()
        fromSnapshot.removeFromSuperview()
        toSnapshot.removeFromSuperview()

        // complete transition
        if !transitionContext.transitionWasCancelled 
            containerView.addSubview(toVC.view)
        
        transitionContext.completeTransition(!transitionContext.transitionWasCancelled)
    )

【问题讨论】:

我在 iOS 13 上遇到了同样的问题,之前工作的动画师坏了。如果toVC没有全屏显示,那么我可以看到fromVC缩小并位于toVC后面,但是,当toVC全屏显示时,当我关闭toVC时,fromVC是黑色的,然后大约一秒钟,内容将恢复 我没有在一秒钟后恢复内容。它只是保持黑色,我必须退出该应用程序。如果您找到解决方法,请告诉我。 【参考方案1】:

上面的答案是正确的将modalPresentationStyle设置为.fullScreen,但是还值得一提的是,如果您的视图控制器嵌入在UINavigationController中,则需要在视图控制器上进行设置:

viewController.modalPresentationStyle = .fullScreen

【讨论】:

【参考方案2】:

这是一个较晚的重播,但我认为你应该尝试我的做法。

呈现视图的代码 -

  let cardsScreen: SideMenuController = SideMenuController(nibName: "SideMenuController", bundle: nil)
  cardsScreen.modalPresentationStyle = .fullScreen
  self.navigationController?.present(cardsScreen, animated: true, completion: nil)

在我的例子中,SideMenuController 是一个 ViewController,我在 Table 上添加动画。

func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) 
    cell.transform = CGAffineTransform(translationX: cell.contentView.frame.width, y: 0)
    UIView.animate(withDuration: 0.5, delay: 0.05 * Double(indexPath.row), usingSpringWithDamping: 0.4, initialSpringVelocity: 0.1,
    options: .curveEaseIn, animations: 
    cell.transform = CGAffineTransform(translationX: cell.contentView.frame.width, y: cell.contentView.frame.height)
    )

而且效果很好。

【讨论】:

以上是关于animateTransition 不再适用于 iOS 13 中模态呈现的 viewController的主要内容,如果未能解决你的问题,请参考以下文章

Laravel 新命令不再适用于 MAC

查询不再适用于 MySQL 5

geocoder.geocodeAddressString 今天不再适用于快速更新

Proguard 不再适用于 Retrofit

UnsafePointer 不再适用于 swift 3

RichPresence 不再适用于 JDA