Wednesday, September 13, 2017

How to rotate a UIView around it's proper center without distortion / skew

Leave a Comment

I've built my own animation engine, and I want to set the rotation of a UI view on each frame that I render (60fps)

I've made a video now showing what the problem is currently.

It's fairly close, but it's still rotating in a strange way:

https://www.youtube.com/watch?v=1ZKK4r0-6i4

I've implemented a custom CustomUIView class, that inherits from UI view. This has translation, scaling and rotation propertys, so when I transform the matrix, all 3 happen in the same action.

var t = CGAffineTransform( translationX: self.translation.x, y:  self.translation.y ); // Apply scaling t = t.scaledBy( x: self.scaling.x, y: self.scaling.y ); // Apply rotation t = t.rotated(by:self.rotation) self.transform = t 

and the size and the width are set like this:

view.frame.size.width = parseSize(value, axis: "width") view.layer.bounds.size.width = parseSize(value, axis: "width")     

I'm trying to set both of these properties, but I'm not sure if this is correct.

I've set the anchor point a lot, and also tried the overall center point of the view as well.

3 Answers

Answers 1

The problem was that I was setting the transform more than once per animation frame. This was causing a compound effect with different values. You need to organise your variables so that you only set the transform once during the property modifications.

Answers 2

Instead of using

var t = CGAffineTransform( translationX: self.translation.x, y:  self.translation.y ); 

use

var t = CGAffineTransform(rotationAngle: CGFloat(Double.pi*self.rotation/180.0)) 

this will rotate your view from a center without changing their position.

Answers 3

This should help you to make it work according to your requirement:

@IBOutlet var scaleRotateImage: UIImageView! func scaleNTransform() -> Void {      scaleRotateImage.layer.cornerRadius = scaleRotateImage.frame.size.height/2.0     scaleRotateImage.clipsToBounds = true      let scaleTransform = CGAffineTransform(scaleX: 3.0, y: 3.0)  // Scale     let rotateTransform = CGAffineTransform(rotationAngle: CGFloat.pi) // Rotation     let hybridTransform = scaleTransform.concatenating(rotateTransform) // Both Scale + Rotation      // Outer block of animation     UIView.animate(withDuration: 5.0, animations: {         self.scaleRotateImage.transform = scaleTransform         self.view.layoutIfNeeded()     }) { (isCompleted) in          // Nested block of animation         UIView.animate(withDuration: 5.0, animations: {             self.scaleRotateImage.transform = hybridTransform             self.view.layoutIfNeeded()         })      }   } 


Result

enter image description here

If You Enjoyed This, Take 5 Seconds To Share It

0 comments:

Post a Comment