Reputation: 65
I don't want the button to rotate, I want it to revolve around a point, just like Earth rotates around the sun. To be noted that I barely have a great knowledge in xcode or swift. So I would suggest a simplest form of code, maybe in the form of function so that I can use it to rotate any number of buttons, around a particular point!
Upvotes: 0
Views: 1084
Reputation: 10199
If you look at earth and sun, there is no rotation involved: The letter "E" (the earth) will never rotate, e.g. the "north pole" will always point to the same direction. Anti-clockwise rotation looks like this:
E
=> | =>
S-E S E-S
(letter "E" is not rotated).
To do this, your animation will have to follow a circle around the sun. Create a view controller with two buttons (sunButton and earthButton), and upon touching the sun, the rotation will start or stop:
// 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()
}
}
Upvotes: 0
Reputation: 41
You can make an extension of a button as below to rotate any instance of button.
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)
Hope this helps!
Upvotes: 1