我按照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