旋转UIButton 180度并将其旋转回来

5

我有一个 UIButton,我希望它能以一个方向旋转 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;
        }];
    }
}

第一次它可以工作,但第二次按按钮时没有反应。有人能解释一下我在这里做错了什么吗?

7个回答

19

最简单的方法是将其旋转一个极小的角度,略小于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;
        }
    }];
}

结果:

旋转演示


我喜欢你的方式。这是Swift 3代码:UIView.animate(withDuration: 0.5, animations: { if self.transform == CGAffineTransform.identity { self.transform = CGAffineTransform(rotationAngle: (180.0 * .pi) / 180.0) } else { self.transform = CGAffineTransform.identity } }) - Tidane

14

这里是@rob mayoff解决方案的Swift3代码。

   @IBAction func fooButton(_ sender: Any) {
        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替代。

@IBAction func fooButton(_ sender: Any) {
    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
        }
    })
 }

11

M_PI-M_PI将产生相同的视觉效果。

转回原来的位置应该是:

self.blurButton.transform = CGAffineTransformMakeRotation(0);

--编辑--

要使计数器逆时针旋转,您可以使用-2*M_PI

self.blurButton.transform = CGAffineTransformMakeRotation(-2*M_PI);

并不是这样的,如果我输入0,它会在同一个方向上进行另一次180度旋转,回到初始位置。但这就像把按钮顺时针旋转360度。相反,我想先进行180度顺时针旋转,然后再进行180度逆时针旋转。 - MegaManX
对于逆时针旋转,您可以使用“-2*M_PI”。 - Leonardo
不确定的话,我刚刚在这里测试过,它运行良好。 - Leonardo
上次那个是我的错,我没有提交代码。请在评论中放置这个答案,以便我可以接受它。 - MegaManX

1

将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)]
    }

您可以查看我的代码示例:https://github.com/issuran/Scrum-Geek-Poker/blob/0d032a4b4edcf75cebae1524131f4fe6be3a5edf/Scrum%20Geek%20Poker/Features/CardCollection/View/MainScreenViewController.swift

0
要“取消旋转”视图,请将变换设置为常量CGAffineTransformIdentity,这是一个零变换。 这就是使用变换的美妙之处,您不需要计算回来的方法,只需撤消您已经执行的操作即可。

您IP地址为143.198.54.68,由于运营成本限制,当前对于免费用户的使用频率限制为每个IP每72小时10次对话,如需解除限制,请点击左下角设置图标按钮(手机用户先点击左上角菜单按钮)。 - MegaManX

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
        })
    }

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")
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接