我设置了一个视图,当应用程序向前导航时,它使用UIViewAnimationOptionTransitionFlipFromRight选项执行transitionFromView。这会产生如下效果:

向后导航使用UIViewAnimationOptionTransitionFlipFromLeft,但在其他方面是相同的。好的,到目前为止,一切都很好。
现在,我还设置了一个UIPanGestureRecognizer,这样我就可以将视图的翻转与用户在屏幕上的水平手势联系起来。但很明显,在这种情况下我不能使用transitionFromView,所以我的手势识别器使用以下命令手动设置layer的transform属性:
CATransform3D transform = CATransform3DIdentity;
transform.m34 = 1.0 / -800.0;
viewToTransform.layer.transform = CATransform3DRotate(transform, M_PI * rotationPercent, 0.0, 1.0, 0.0);但这产生了一个微妙的不同效果:

在transitionFromView的UIViewAnimationOptionTransitionFlipFromRight选项中,视图在翻转动画期间缩放,以便翻转视图的最高边保持容器视图的高度。但是,当手动执行layer的transform时,视图的中心保持恒定大小,在动画过程中稍微裁剪翻转视图较长边的边角。
在手势识别器中设置layer的transform属性时,如何实现此效果(我可能还想调整opacity,以获得transitionFromView实现的略微变暗的效果)。我想我可以使用CATransform3DMakeScale并根据旋转的角度和我特定的m34设置手动计算缩放函数,但是在我完成这个练习之前,我想确保我没有忽略一些更直观或自然的方法来实现标准翻转动画所需的同时缩放和旋转。即使我必须手动计算缩放因子,我也会很感激如何将其定义为m34设置和角度的函数(我不是矢量变换的微妙之处的专家)。
发布于 2013-04-06 22:57:03
变换都是基于你的层anchorPoint的。这就是你旋转的“轴心点”。
anchorPoint在x和y中都使用从0到1的范围,缺省为0.5,0.5
我相信你会希望你的层的锚点是这样的:
viewToTransform.layer.anchorPoint = CGPointMake(0.5, 1);在这个问题的答案中有一些很好的信息和研究地点:
发布于 2017-02-14 04:49:52
HalR是正确的,为了达到预期的效果,应该改变anchorPoint。因此,对于围绕视图右边缘旋转的水平翻转,可以按如下方式设置锚点:
viewToTransform.layer.anchorPoint = CGPointMake(1, 0.5);但是,这也会改变视图,因此需要将新的anchorPoint与CATransform3D值结合起来,将视图转换回原来的位置。例如,这是一个执行水平翻转动画的Swift 3自定义变换“动画控制器”。
class HorizontalFlipAnimationController: NSObject, UIViewControllerAnimatedTransitioning {
enum TransitionType {
case presenting
case dismissing
}
let transitionType: TransitionType
init(transitionType: TransitionType) {
self.transitionType = transitionType
super.init()
}
func animateTransition(using transitionContext: UIViewControllerContextTransitioning) {
let inView = transitionContext.containerView
let toView = transitionContext.view(forKey: .to)!
let fromView = transitionContext.view(forKey: .from)!
var frame = inView.bounds
func flipTransform(angle: CGFloat, offset: CGFloat = 0) -> CATransform3D {
var transform = CATransform3DMakeTranslation(offset, 0, 0)
transform.m34 = -1.0 / 1600
transform = CATransform3DRotate(transform, angle, 0, 1, 0)
return transform
}
toView.frame = inView.bounds
toView.alpha = 0
let transformFromStart: CATransform3D
let transformFromEnd: CATransform3D
let transformFromMiddle: CATransform3D
let transformToStart: CATransform3D
let transformToMiddle: CATransform3D
let transformToEnd: CATransform3D
switch transitionType {
case .presenting:
transformFromStart = flipTransform(angle: 0, offset: inView.bounds.size.width / 2)
transformFromEnd = flipTransform(angle: -.pi, offset: inView.bounds.size.width / 2)
transformFromMiddle = flipTransform(angle: -.pi / 2)
transformToStart = flipTransform(angle: .pi, offset: -inView.bounds.size.width / 2)
transformToMiddle = flipTransform(angle: .pi / 2)
transformToEnd = flipTransform(angle: 0, offset: -inView.bounds.size.width / 2)
toView.layer.anchorPoint = CGPoint(x: 0, y: 0.5)
fromView.layer.anchorPoint = CGPoint(x: 1, y: 0.5)
case .dismissing:
transformFromStart = flipTransform(angle: 0, offset: -inView.bounds.size.width / 2)
transformFromEnd = flipTransform(angle: .pi, offset: -inView.bounds.size.width / 2)
transformFromMiddle = flipTransform(angle: .pi / 2)
transformToStart = flipTransform(angle: -.pi, offset: inView.bounds.size.width / 2)
transformToMiddle = flipTransform(angle: -.pi / 2)
transformToEnd = flipTransform(angle: 0, offset: inView.bounds.size.width / 2)
toView.layer.anchorPoint = CGPoint(x: 1, y: 0.5)
fromView.layer.anchorPoint = CGPoint(x: 0, y: 0.5)
}
toView.layer.transform = transformToStart
fromView.layer.transform = transformFromStart
inView.addSubview(toView)
UIView.animateKeyframes(withDuration: self.transitionDuration(using: transitionContext), delay: 0, options: [], animations: {
UIView.addKeyframe(withRelativeStartTime: 0, relativeDuration: 0.0) {
toView.alpha = 0
fromView.alpha = 1
}
UIView.addKeyframe(withRelativeStartTime: 0, relativeDuration: 0.5) {
toView.layer.transform = transformToMiddle
fromView.layer.transform = transformFromMiddle
}
UIView.addKeyframe(withRelativeStartTime: 0.5, relativeDuration: 0.0) {
toView.alpha = 1
fromView.alpha = 0
}
UIView.addKeyframe(withRelativeStartTime: 0.5, relativeDuration: 0.5) {
toView.layer.transform = transformToEnd
fromView.layer.transform = transformFromEnd
}
}, completion: { finished in
toView.layer.transform = CATransform3DIdentity
fromView.layer.transform = CATransform3DIdentity
toView.layer.anchorPoint = CGPoint(x: 0.5, y: 0.5)
fromView.layer.anchorPoint = CGPoint(x: 0.5, y: 0.5)
transitionContext.completeTransition(!transitionContext.transitionWasCancelled)
})
}
func transitionDuration(using transitionContext: UIViewControllerContextTransitioning?) -> TimeInterval {
return 1.0
}
}这就产生了:

https://stackoverflow.com/questions/15844711
复制相似问题