iOS 利用CATransform3D制作立方体

 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,则景深效果越明显。

  

上面这种方法称之为透视变形。

 

还有一种方法:利用CATransformLayer制作立方体

 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只能用于表示图层的显示顺序,而无法用来决定空间定位。


 

posted @ 2015-05-06 18:20  oumygade  阅读(880)  评论(0编辑  收藏  举报