1 #import <UIKit/UIKit.h>
2 #import <QuartzCore/QuartzCore.h>
3
4 @interface BoxViewController : UIViewController 5 @property (nonatomic, readwrite, strong) CALayer *topLayer; 6 @property (nonatomic, readwrite, strong) CALayer *bottomLayer; 7 @property (nonatomic, readwrite, strong) CALayer *leftLayer; 8 @property (nonatomic, readwrite, strong) CALayer *rightLayer; 9 @property (nonatomic, readwrite, strong) CALayer *frontLayer; 10 @property (nonatomic, readwrite, strong) CALayer *backLayer; 11 @end
1 #import "BoxViewController.h"
2
3 @implementation BoxViewController 4
5 const CGFloat kSize = 100.; 6 const CGFloat kPanScale = 1./100.; 7
8 - (CALayer *)layerWithColor:(UIColor *)color 9 transform:(CATransform3D)transform { 10 CALayer *layer = [CALayer layer]; 11 layer.backgroundColor = [color CGColor]; 12 layer.bounds = CGRectMake(0, 0, kSize, kSize); 13 layer.position = self.view.center; 14 layer.transform = transform; 15 [self.view.layer addSublayer:layer]; 16 return layer; 17 } 18
19 static CATransform3D MakePerspetiveTransform() { 20 CATransform3D perspective = CATransform3DIdentity; 21 perspective.m34 = -1./2000.; 22 return perspective; 23 } 24
25 - (void)viewDidLoad { 26 [super viewDidLoad]; 27
28 CATransform3D transform; 29 transform = CATransform3DMakeTranslation(0, -kSize/2, 0); 30 transform = CATransform3DRotate(transform, M_PI_2, 1.0, 0, 0); 31 self.topLayer = [self layerWithColor:[UIColor redColor] 32 transform:transform]; 33
34 transform = CATransform3DMakeTranslation(0, kSize/2, 0); 35 transform = CATransform3DRotate(transform, M_PI_2, 1.0, 0, 0); 36 self.bottomLayer = [self layerWithColor:[UIColor greenColor] 37 transform:transform]; 38
39 transform = CATransform3DMakeTranslation(kSize/2, 0, 0); 40 transform = CATransform3DRotate(transform, M_PI_2, 0, 1, 0); 41 self.rightLayer = [self layerWithColor:[UIColor blueColor] 42 transform:transform]; 43
44 transform = CATransform3DMakeTranslation(-kSize/2, 0, 0); 45 transform = CATransform3DRotate(transform, M_PI_2, 0, 1, 0); 46 self.leftLayer = [self layerWithColor:[UIColor cyanColor] 47 transform:transform]; 48
49 transform = CATransform3DMakeTranslation(0, 0, -kSize/2); 50 transform = CATransform3DRotate(transform, M_PI_2, 0, 0, 0); 51 self.backLayer = [self layerWithColor:[UIColor yellowColor] 52 transform:transform]; 53
54 transform = CATransform3DMakeTranslation(0, 0, kSize/2); 55 transform = CATransform3DRotate(transform, M_PI_2, 0, 0, 0); 56 self.frontLayer = [self layerWithColor:[UIColor magentaColor] 57 transform:transform]; 58
59 self.view.layer.sublayerTransform = MakePerspetiveTransform(); 60
61 UIGestureRecognizer *g = [[UIPanGestureRecognizer alloc] 62 initWithTarget:self 63 action:@selector(pan:)]; 64 [self.view addGestureRecognizer:g]; 65 } 66
67 - (void)pan:(UIPanGestureRecognizer *)recognizer { 68 CGPoint translation = [recognizer translationInView:self.view]; 69 CATransform3D transform = MakePerspetiveTransform(); 70 transform = CATransform3DRotate(transform, 71 kPanScale * translation.x, 72 0, 1, 0); 73 transform = CATransform3DRotate(transform, 74 -kPanScale * translation.y, 75 1, 0, 0); 76 self.view.layer.sublayerTransform = transform; 77 } 78
79 @end
第59行的 self.view.layer.sublayerTransform = MakePerspetiveTransform(); 是给self.view.layer的子图层添加 景深效果,之所以有景深效果,是因为perspective.m34 = -1./2000.
m34的值越接近0,则景深效果越明显。
1 #import <UIKit/UIKit.h>
2 #import <QuartzCore/QuartzCore.h>
3
4 @interface BoxTransformViewController : UIViewController 5 @property (nonatomic, readwrite, strong) CALayer *contentLayer; 6 @property (nonatomic, readwrite, strong) CALayer *topLayer; 7 @property (nonatomic, readwrite, strong) CALayer *bottomLayer; 8 @property (nonatomic, readwrite, strong) CALayer *leftLayer; 9 @property (nonatomic, readwrite, strong) CALayer *rightLayer; 10 @property (nonatomic, readwrite, strong) CALayer *frontLayer; 11 @property (nonatomic, readwrite, strong) CALayer *backLayer; 12
13 @end
1 #import "BoxTransformViewController.h"
2
3 @implementation BoxTransformViewController 4
5 const CGFloat kSize = 100.; 6 const CGFloat kPanScale = 1./100.; 7
8 - (CALayer *)layerAtX:(CGFloat)x y:(CGFloat)y z:(CGFloat)z 9 color:(UIColor *)color 10 transform:(CATransform3D)transform { 11 CALayer *layer = [CALayer layer]; 12 layer.backgroundColor = [color CGColor]; 13 layer.bounds = CGRectMake(0, 0, kSize, kSize); 14 layer.position = CGPointMake(x, y); 15 layer.zPosition = z; 16 layer.transform = transform; 17 [self.contentLayer addSublayer:layer]; 18 return layer; 19 } 20
21 static CATransform3D MakeSideRotation(CGFloat x, CGFloat y, CGFloat z) { 22 return CATransform3DMakeRotation(M_PI_2, x, y, z); 23 } 24
25 - (void)viewDidLoad { 26 [super viewDidLoad]; 27 CATransformLayer *contentLayer = [CATransformLayer layer]; 28 contentLayer.frame = self.view.layer.bounds; 29 CGSize size = contentLayer.bounds.size; 30 contentLayer.transform =
31 CATransform3DMakeTranslation(size.width/2, size.height/2, 0); 32 [self.view.layer addSublayer:contentLayer]; 33
34 self.contentLayer = contentLayer; 35
36 self.topLayer = [self layerAtX:0 y:-kSize/2 z:0
37 color:[UIColor redColor] 38 transform:MakeSideRotation(1, 0, 0)]; 39
40 self.bottomLayer = [self layerAtX:0 y:kSize/2 z:0
41 color:[UIColor greenColor] 42 transform:MakeSideRotation(1, 0, 0)]; 43
44 self.rightLayer = [self layerAtX:kSize/2 y:0 z:0
45 color:[UIColor blueColor] 46 transform:MakeSideRotation(0, 1, 0)]; 47
48 self.leftLayer = [self layerAtX:-kSize/2 y:0 z:0
49 color:[UIColor cyanColor] 50 transform:MakeSideRotation(0, 1, 0)]; 51
52 self.backLayer = [self layerAtX:0 y:0 z:-kSize/2
53 color:[UIColor yellowColor] 54 transform:CATransform3DIdentity]; 55
56 self.frontLayer = [self layerAtX:0 y:0 z:kSize/2
57 color:[UIColor magentaColor] 58 transform:CATransform3DIdentity]; 59
60 UIGestureRecognizer *g = [[UIPanGestureRecognizer alloc] 61 initWithTarget:self 62 action:@selector(pan:)]; 63 [self.view addGestureRecognizer:g]; 64 } 65
66 - (void)pan:(UIPanGestureRecognizer *)recognizer { 67 CGPoint translation = [recognizer translationInView:self.view]; 68 CATransform3D transform = CATransform3DIdentity; 69 transform = CATransform3DRotate(transform, 70 kPanScale * translation.x, 71 0, 1, 0); 72 transform = CATransform3DRotate(transform, 73 -kPanScale * translation.y, 74 1, 0, 0); 75 self.view.layer.sublayerTransform = transform; 76 } 77
78 @end
它同样实现了立方体的3维旋转效果,但是如果把代码中的
CATransformLayer *contentLayer = [CATransformLayer layer]; 改成 CALayer *contentLayer = [CALayer layer];
旋转的效果将是下面这种,“立方体”成扁平的了。
如果不是因为有CATransformLayer,那么上述代码中的添加立方体的各个面时,用到的zPosition只能用于表示图层的显示顺序,而无法用来决定空间定位。