如何在 Xcode 中围绕一个点或 UIView 的中心旋转 Button?

How to rotate a Button around a point or the center of a UIView in Xcode?

我不希望按钮旋转,我希望它围绕一个点旋转,就像地球围绕太阳旋转一样。 需要注意的是,我对 xcode 或 swift 知之甚少。所以我会建议一种最简单的代码形式,也许是函数形式,这样我就可以用它来围绕特定点旋转任意数量的按钮!

您可以像下面这样扩展一个按钮来旋转任何按钮实例。

extension UIButton {

    func rotate(angle: CGFloat) {
        let radians = angle / 180.0 * CGFloat(Double.pi)
        self.transform = self.transform.rotated(by: radians);
    }
}

// Call to rotate button as below from wherever you require in your code
let myButton = UIButton()
myButton.rotate(angle: 180)

希望对您有所帮助!

如果你看地球和太阳,不涉及自转:字母 "E"(地球)永远不会自转,例如"north pole" 将始终指向同一方向。 Anti-clockwise 旋转看起来像这样:

                 E            
         =>      |     => 
S-E              S          E-S

(字母"E"没有旋转)。

为此,您的动画必须围绕太阳转一圈。 创建一个带有两个按钮(sunButton 和 earthButton)的视图控制器,当触摸到太阳时,旋转将开始或停止:

// some helper extension
extension CGPoint {
    static func distanceBetween(point p1: CGPoint,
                                andPoint p2: CGPoint) -> CGFloat {
        return sqrt(pow((p2.x - p1.x), 2) + pow((p2.y - p1.y), 2))
    }

    static func angle(from fromPoint: CGPoint, to toPoint: CGPoint) -> CGFloat {
        let dx: CGFloat = fromPoint.x - toPoint.x
        let dy: CGFloat = fromPoint.y - toPoint.y
        let radians: CGFloat = atan2(dy, dx)
        return radians
    }

}

class ViewController: UIViewController {

    @IBOutlet weak var sunButton: UIButton!
    @IBOutlet weak var earthButton: UIButton!

    var isRevolving = false

    @IBAction func sunPressed(_ sender: Any) {
        if (!isRevolving) {
            startRevolving()
        } else {
            stopRevolving()
        }
    }

    func startRevolving() {
        isRevolving = true
        let sunCenter = sunButton.center
        let earthCenter = earthButton.center

        let distance = CGPoint.distanceBetween(point: sunCenter, andPoint: earthCenter)
        var angle = CGPoint.angle(from: sunCenter, to: earthCenter)
        angle = .pi + angle

        let circlePath = UIBezierPath(arcCenter: sunCenter, radius: distance, startAngle: angle + .pi*2, endAngle: angle, clockwise: false)
        // for clockwise rotation, use:
        //let circlePath = UIBezierPath(arcCenter: sunCenter, radius: distance, startAngle: angle, endAngle: angle + .pi*2, clockwise: true)

        let animation = CAKeyframeAnimation(keyPath: #keyPath(CALayer.position))
        animation.duration = 5
        animation.repeatCount = MAXFLOAT
        animation.path = circlePath.cgPath

        earthButton.layer.add(animation, forKey: nil)
    }

    func stopRevolving() {
        isRevolving = false
        if let currentPosition = earthButton.layer.presentation()?.position {
            earthButton.center = currentPosition
        }
        earthButton.layer.removeAllAnimations()
    }

}