我有UIButton
,我希望在一个方向上旋转180度,然后再旋转180度。我使用CABasicAnimation
做了一段时间的动画,但这次我想用变换来做。这是我写的代码:
- (IBAction)blurAction:(id)sender {
if (self.blurActive) {
[UIView animateWithDuration:0.1 animations:^{
self.blurView.alpha = 0;
self.blurButton.transform = CGAffineTransformMakeRotation(M_PI);
} completion:^(BOOL finished) {
self.blurActive = NO;
}];
}
else {
[UIView animateWithDuration:0.1 animations:^{
self.blurView.alpha = 1;
self.blurButton.transform = CGAffineTransformMakeRotation(-M_PI);
} completion:^(BOOL finished) {
self.blurActive = YES;
}];
}
}
它第一次工作,但第二次按下按钮,没有任何反应。有人可以解释我在这里做错了吗?
答案 0 :(得分:15)
实现这种效果的最简单方法就是旋转一个小于180°的微小量:
- (IBAction)toggle:(UIButton *)sender {
[UIView animateWithDuration:0.2 animations:^{
if (CGAffineTransformEqualToTransform(sender.transform, CGAffineTransformIdentity)) {
sender.transform = CGAffineTransformMakeRotation(M_PI * 0.999);
} else {
sender.transform = CGAffineTransformIdentity;
}
}];
}
结果:
答案 1 :(得分:8)
M_PI
和-M_PI
将具有相同的视觉效果
转回原来的位置应该是
self.blurButton.transform = CGAffineTransformMakeRotation(0);
- 编辑 -
要为逆时针旋转设置动画,您可以使用-2*M_PI
self.blurButton.transform = CGAffineTransformMakeRotation(-2*M_PI);
答案 2 :(得分:8)
以下是@rob mayoff解决方案的 Swift3 代码。
UIView.animate(withDuration:0.1, animations: { () -> Void in
if sender.transform == .identity {
sender.transform = CGAffineTransform(rotationAngle: CGFloat(M_PI * 0.999))
} else {
sender.transform = .identity
}
})
<强> Swift4 强>
M_PI
已弃用,已替换为Double.pi
UIView.animate(withDuration:0.1, animations: { () -> Void in
if sender.transform == .identity {
sender.transform = CGAffineTransform(rotationAngle: CGFloat(Double.pi * 0.999))
} else {
sender.transform = .identity
}
})
答案 3 :(得分:2)
将UIButton旋转180º
UIButton.transform = CGAffineTransform(rotationAngle: CGFloat(Double.pi))
将UIButton旋转0º或再次返回
UIButton.transform = CGAffineTransform(rotationAngle: 0)
设置动画的示例
if cardViewModel.getBottomMenuVisibility() {
[UIView .transition(
with: bottomMenuView,
duration: 0.3,
options: .transitionCrossDissolve,
animations: {
// Turn UIButton upside down
self.bottomMenu.transform = CGAffineTransform(rotationAngle: CGFloat(Double.pi))
},
completion: nil)]
}
else {
[UIView .transition(
with: bottomMenuView,
duration: 0.3,
options: .transitionCrossDissolve,
animations: {
// Turn UIButton back to normal
self.bottomMenu.transform = CGAffineTransform(rotationAngle: 0)
},
completion: nil)]
}
答案 4 :(得分:0)
要旋转&#39;视图将变换设置为常量CGAffineTransformIdentity,它是零的变换。这是使用变换的美妙之处,你不需要计算回来的方式,只需撤消你已经做过的事情。
答案 5 :(得分:0)
您无法通过变换实际实现此目的,因为变换仅保存有关结束状态的信息。它们没有告诉我们应该使用哪个方向来制作,例如轮换。
实现180度前后旋转行为的最佳选择是使用CABasicAnimation
。
以下是例子:
func rotateImage(forward: Bool) {
let rotationAnimation = CABasicAnimation(keyPath: "transform.rotation.z")
rotationAnimation.fromValue = forward ? 0.0 : CGFloat.pi
rotationAnimation.toValue = forward ? CGFloat.pi : 0.0
rotationAnimation.fillMode = kCAFillModeForwards
rotationAnimation.isRemovedOnCompletion = false
rotationAnimation.duration = 0.5
handleImageView.layer.add(rotationAnimation, forKey: "rotationAnimation")
}
答案 6 :(得分:0)
Swift 4+
@IBAction private func maximizeButtonAction(_ sender: UIButton) {
UIView.animate(withDuration: 0.2, animations: {
sender.transform = sender.transform == .identity ? CGAffineTransform(rotationAngle: CGFloat(Double.pi * 0.999)) : .identity
})
}