My swift code below is trying to rotate a imageview around another imageview. I want the rotation to work just like a game spinner. A link to something close to what I am looking for is https://www.orientaltrading.com/large-spinner-wheel-stand-up-a2-13846120.fltr. Right now my code is not doing that you can see in the gif below what the code is currently doing. The gif is not doing what I want it to. I want the bottom anchor of the pink box to be its center bottom anchor which is attached to the center of the uiviewcontroller. That rotates 180 degrees in one way. Just like a game spinner in the link above.
import UIKit
class ViewController: UIViewController {
var box = UIImageView()
var box1 = UIImageView()
override func viewDidLoad() {
super.viewDidLoad()
box.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(box)
box.backgroundColor = .systemPink
box1.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(box1)
box1.backgroundColor = .purple
self.box.setAnchorPoint(anchorPoint: CGPoint(x: 0.5, y: 0.5))
Rotate()
NSLayoutConstraint.activate([
box.heightAnchor.constraint(equalTo: view.heightAnchor, multiplier: 0.25),
box.widthAnchor.constraint(equalTo: view.widthAnchor, multiplier: 0.25),
box.centerXAnchor.constraint(equalTo: view.centerXAnchor),
box.bottomAnchor.constraint(equalTo: view.centerYAnchor),
box1.heightAnchor.constraint(equalTo: view.heightAnchor, multiplier: 0.05),
box1.widthAnchor.constraint(equalTo: view.heightAnchor, multiplier: 0.05),
box1.centerXAnchor.constraint(equalTo: view.centerXAnchor),
box1.centerYAnchor.constraint(equalTo: view.centerYAnchor)
])
// Do any additional setup after loading the view.
}
func Rotate(){
let rotation = UIViewPropertyAnimator(duration: 25, curve: .linear, animations: {
self.box.transform = self.box.transform.rotated(by: CGFloat.pi/0.94)
})
rotation.startAnimation()
}
}
extension UIView{
func setAnchorPoint(anchorPoint: CGPoint) {
var newPoint = CGPoint(x: self.bounds.size.width * anchorPoint.x, y: self.bounds.size.height * anchorPoint.y)
var oldPoint = CGPoint(x: self.bounds.size.width * self.layer.anchorPoint.x, y: self.bounds.size.height * self.layer.anchorPoint.y)
newPoint = newPoint.applying(self.transform)
oldPoint = oldPoint.applying(self.transform)
var position : CGPoint = self.layer.position
position.x -= oldPoint.x
position.x += newPoint.x;
position.y -= oldPoint.y;
position.y += newPoint.y;
self.layer.position = position;
self.layer.anchorPoint = anchorPoint;
}
}
There are two problems with your code:
bounds
are (0, 0, 0, 0).Delete setAnchorPoint
and Rotate
calls from view did load and add method like this:
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
view.setNeedsLayout()
view.layoutIfNeeded()
self.box.setAnchorPoint(anchorPoint: CGPoint(x: 0.5, y: 1))
Rotate()
}
In viewWillAppear
size of controllers view has been already set. And calling view.setNeedsLayout()
and view.layoutIfNeeded()
layout your boxes. You can check box
frame before and after these calls.