Swift iOS -Flicker和UIWindow的黑色背景显示在Zoom Image Transition推送和弹出

时间:2018-06-03 20:45:17

标签: ios swift uinavigationcontroller caanimation catransition

我按照older tutorial创建了像Apple News应用程序一样的缩放图像转换。我不得不对代码进行一些调整,以使其最终完成。问题是我注意到变焦非常平滑,放大和缩小时闪烁,推出弹出时UIWindow的黑色背景显示。

导致闪烁的原因是什么?在过渡时如何掩盖窗口的黑色背景?

class ThumbnailZoomTransitionAnimator: NSObject, UIViewControllerAnimatedTransitioning {

private let duration: TimeInterval = 0.5
var operation: UINavigationControllerOperation = .push
var thumbnailFrame = CGRect.zero

func transitionDuration(using transitionContext: UIViewControllerContextTransitioning?) -> TimeInterval {
    return duration
}

func animateTransition(using transitionContext: UIViewControllerContextTransitioning) {

   let presenting: Bool = operation == .push

    guard let fromView: UIView  = transitionContext.view(forKey: UITransitionContextViewKey.from) else { return }
    guard let toView: UIView  = transitionContext.view(forKey: UITransitionContextViewKey.to) else { return }
    let containerView: UIView  = transitionContext.containerView

    let startingView: UIView = presenting ? fromView : toView
    let endingView: UIView = presenting ? toView : fromView

    let anchorPoint: CGPoint = fromView.layer.anchorPoint
    let position: CGPoint = fromView.layer.position

    var initialFrame: CGRect = presenting ? thumbnailFrame : endingView.frame
    let finalFrame: CGRect = presenting ? endingView.frame : thumbnailFrame

    let initialFrameAspectRatio: CGFloat = initialFrame.width / initialFrame.height
    let endingViewAspectRatio: CGFloat = endingView.frame.width / endingView.frame.height

    if initialFrameAspectRatio > endingViewAspectRatio {
        initialFrame.size = CGSize(width: initialFrame.height * endingViewAspectRatio, height: initialFrame.height)
    }
    else {
        initialFrame.size = CGSize(width: initialFrame.width, height: initialFrame.width / endingViewAspectRatio)
    }

    let finalFrameAspectRatio: CGFloat = finalFrame.width / finalFrame.height
    var resizedFinalFrame: CGRect = finalFrame
    if finalFrameAspectRatio > endingViewAspectRatio {
        resizedFinalFrame.size = CGSize(width: finalFrame.height * endingViewAspectRatio, height: finalFrame.height)
    }
    else {
        resizedFinalFrame.size = CGSize(width: finalFrame.width, height: finalFrame.width / endingViewAspectRatio)
    }

    let scaleFactor = resizedFinalFrame.width / initialFrame.width
    let growScaleFactor = presenting ? scaleFactor: 1/scaleFactor
    let shrinkScaleFactor = 1/growScaleFactor

    if presenting {
        var transform = CGAffineTransform.identity
        transform = transform.scaledBy(x: shrinkScaleFactor, y: shrinkScaleFactor)

        endingView.transform = transform
        endingView.center = CGPoint(x: thumbnailFrame.midX, y: thumbnailFrame.midY)
        endingView.clipsToBounds = true
    }

    endingView.alpha = presenting ? 0 : 1
    startingView.alpha = presenting ? 1 : 0

    containerView.addSubview(toView)
    containerView.bringSubview(toFront: endingView)

    UIView.animate(withDuration: duration, delay: 0.0, usingSpringWithDamping: 1, initialSpringVelocity: 0.0, options: [], animations: {

        endingView.alpha = presenting ? 1 : 0
        startingView.alpha = presenting ? 0 : 1

        if presenting {

            var transform = CGAffineTransform.identity
            transform = transform.translatedBy(x: startingView.frame.midX - self.thumbnailFrame.midX, y: startingView.frame.midY - self.thumbnailFrame.midY)
            transform = transform.scaledBy(x: growScaleFactor, y: growScaleFactor)

            startingView.transform = transform
            endingView.transform = CGAffineTransform.identity
        }
        else {

            startingView.transform = CGAffineTransform.identity
            endingView.transform = CGAffineTransform(scaleX: shrinkScaleFactor, y: shrinkScaleFactor)
        }

        endingView.center = CGPoint(x: finalFrame.midX, y: finalFrame.midY)
        startingView.transform = CGAffineTransform.identity
    }) { (finished) in
        transitionContext.completeTransition(!transitionContext.transitionWasCancelled)
    }
}

我在这里进行了调整:

if presenting {

    var transform = CGAffineTransform.identity
    transform = transform.translatedBy(x: startingView.frame.midX - self.thumbnailFrame.midX, y: startingView.frame.midY - self.thumbnailFrame.midY)
    transform = transform.scaledBy(x: growScaleFactor, y: growScaleFactor)

    startingView.transform = transform
    endingView.transform = CGAffineTransform.identity
}else {

    startingView.transform = CGAffineTransform.identity
    endingView.transform = CGAffineTransform(scaleX: shrinkScaleFactor, y: shrinkScaleFactor)
}

endingView.center = CGPoint(x: finalFrame.midX, y: finalFrame.midY)
startingView.transform = CGAffineTransform.identity

0 个答案:

没有答案