How to rotate a flat object around its center in perspective view? How to rotate a flat object around its center in perspective view? ios ios

How to rotate a flat object around its center in perspective view?


This is easiest if you use a CATransformLayer as the parent of the image view's layer. So you'll need a custom view subclass that uses CATransformLayer as its layer. This is trivial:

@interface TransformView : UIView@end@implementation TransformView+ (Class)layerClass {    return [CATransformLayer class];}@end

Put a TransformView in your nib, and add a UIImageView as a subview of the TransformView. Connect these views to outlets in your view controller called transformView and discView.

In your view controller, set the transform of transformView to apply perspective (by setting m34) and the X-axis tilt:

- (void)viewDidLoad{    [super viewDidLoad];    CATransform3D transform = CATransform3DIdentity;    transform.m34 = -1 / 500.0;    transform = CATransform3DRotate(transform, .85 * M_PI_2, 1, 0, 0);    self.transformView.layer.transform = transform;}

Add an animation for key path transform.rotation.z to discView in viewWillAppear: and remove it in viewDidDisappear::

- (void)viewWillAppear:(BOOL)animated {    [super viewWillAppear:animated];    CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"transform.rotation.z"];    animation.fromValue = [NSNumber numberWithFloat:0];    animation.toValue = [NSNumber numberWithFloat:2 * M_PI];    animation.duration = 1.0;    animation.repeatCount = HUGE_VALF;    animation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear];    [self.discView.layer addAnimation:animation forKey:@"transform.rotation.z"];}- (void)viewDidDisappear:(BOOL)animated {    [super viewDidDisappear:animated];    [self.discView.layer removeAllAnimations];}

Result:

spinning disc

UPDATE

Here's a Swift playground demonstration:

import UIKitimport XCPlaygroundclass TransformView: UIView {    override class func layerClass() -> AnyClass {        return CATransformLayer.self    }}let view = UIView(frame: CGRectMake(0, 0, 300, 150))view.backgroundColor = UIColor.groupTableViewBackgroundColor()XCPlaygroundPage.currentPage.liveView = viewlet transformView = TransformView(frame: view.bounds)view.addSubview(transformView)var transform = CATransform3DIdentitytransform.m34 = CGFloat(-1) / transformView.bounds.widthtransform = CATransform3DRotate(transform, 0.85 * CGFloat(M_PI_2), 1, 0, 0)transformView.layer.transform = transformlet image = UIImage(named: "3DgoldRecord")!let imageView = UIImageView(image: image)imageView.bounds = CGRectMake(0, 0, 200, 200)imageView.center = CGPointMake(transformView.bounds.midX, transformView.bounds.midY)transformView.addSubview(imageView)let animation = CABasicAnimation(keyPath: "transform.rotation.z")animation.fromValue = 0animation.toValue = 2 * M_PIanimation.duration = 1animation.repeatCount = Float.infinityanimation.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionLinear)imageView.layer.addAnimation(animation, forKey: animation.keyPath)

Copy the image from the question into the playground Resources folder and name it 3DgoldRecord.png. Result:

playground result


You may consider wrapping the recordLayer with a superlayer. Apply the x-axis rotation to the superlayer and add the z-axis rotation animation to recordLayer.