我正在使用自定义过渡来显示全屏模式游戏视图。当用户启动游戏时,根视图控制器将“缩小”到屏幕上,而全屏游戏视图控制器将从更大的比例缩小到显示,同时从0%不透明度过渡到100%不透明度。简单!
过渡效果很好,工作正常,在关闭游戏视图控制器时也可以正确反转动画。
我遇到的问题是,如果在显示全屏游戏视图控制器的同时旋转设备,则在返回到根视图控制器时,布局就很麻烦了。而且进一步旋转并不能解决问题,布局是螺旋状且保持螺旋状。
如果我禁用自定义过渡的使用,此问题将消失。另外,如果我保留自定义过渡,但禁用在过渡动画中在源视图和目标视图上设置CATransform3D的调用,问题将再次消失。
这是我的过渡代表:
class FullscreenModalTransitionManager: NSObject, UIViewControllerAnimatedTransitioning, UIViewControllerTransitioningDelegate {
private var presenting:Bool = true
// MARK: UIViewControllerAnimatedTransitioning protocol methods
func animateTransition(transitionContext: UIViewControllerContextTransitioning) {
// get reference to our fromView, toView and the container view that we should perform the transition in
let container = transitionContext.containerView()
let fromView = transitionContext.viewForKey(UITransitionContextFromViewKey)!
let toView = transitionContext.viewForKey(UITransitionContextToViewKey)!
let scale:CGFloat = 1.075
//let bigScale = CGAffineTransformMakeScale(scale, scale)
//let smallScale = CGAffineTransformMakeScale(1/scale,1/scale)
let bigScale = CATransform3DMakeScale(scale, scale, 1)
let smallScale = CATransform3DMakeScale(1/scale, 1/scale, 1)
let smallOpacity:CGFloat = 0.5
let presenting = self.presenting
if presenting {
// when presenting, incoming view must be on top
container.addSubview(fromView)
container.addSubview(toView)
toView.layer.transform = bigScale
toView.opaque = false
toView.alpha = 0
fromView.layer.transform = CATransform3DIdentity
fromView.opaque = false
fromView.alpha = 1
} else {
// when !presenting, outgoing view must be on top
container.addSubview(toView)
container.addSubview(fromView)
toView.layer.transform = smallScale
toView.opaque = false
toView.alpha = smallOpacity
fromView.layer.transform = CATransform3DIdentity
fromView.opaque = false
fromView.alpha = 1
}
let duration = self.transitionDuration(transitionContext)
UIView.animateWithDuration(duration,
delay: 0.0,
usingSpringWithDamping: 0.7,
initialSpringVelocity: 0,
options: nil,
animations: {
if presenting {
fromView.layer.transform = smallScale
fromView.alpha = smallOpacity
} else {
fromView.layer.transform = bigScale
fromView.alpha = 0
}
},
completion: nil )
UIView.animateWithDuration(duration,
delay: duration/6,
usingSpringWithDamping: 0.7,
initialSpringVelocity: 0.5,
options: nil,
animations: {
toView.layer.transform = CATransform3DIdentity
toView.alpha = 1
},
completion: { finished in
transitionContext.completeTransition(true)
})
}
func transitionDuration(transitionContext: UIViewControllerContextTransitioning) -> NSTimeInterval {
return 0.5
}
// MARK: UIViewControllerTransitioningDelegate protocol methods
func animationControllerForPresentedController(presented: UIViewController, presentingController presenting: UIViewController, sourceController source: UIViewController) -> UIViewControllerAnimatedTransitioning? {
self.presenting = true
return self
}
func animationControllerForDismissedController(dismissed: UIViewController) -> UIViewControllerAnimatedTransitioning? {
self.presenting = false
return self
}
}
并且,为视觉参考,这是我的根视图控制器通常的外观:
并且,作为视觉参考,这是在游戏视图中旋转设备(至少一次)并返回到根视图控制器时,根视图控制器的外观。
最后一点-以防万一-我正在使用自动布局和大小类来布局我的根视图控制器。
谢谢,
在对具有非身份转换的视图进行一些手动布局代码时,我不小心想到了这一点。事实证明,如果您的视图具有非身份转换,则正常的布局代码将失败。
我的过渡委托中的解决方法是采用过渡视图,并在动画完整回调中将其变换设置为标识(因为该视图在动画末尾以及在新视图之后不可见,因此对外观)
UIView.animateWithDuration(duration,
delay: 0.0,
usingSpringWithDamping: 0.7,
initialSpringVelocity: 0,
options: nil,
animations: {
if presenting {
fromView.transform = smallScale
fromView.alpha = smallOpacity
} else {
fromView.transform = bigScale
fromView.alpha = 0
}
},
completion: { completed in
// set transform of now hidden view to identity to prevent breakage during rotation
fromView.transform = CGAffineTransformIdentity
})
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句