如何在 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()
}
}
我不希望按钮旋转,我希望它围绕一个点旋转,就像地球围绕太阳旋转一样。 需要注意的是,我对 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()
}
}