Skip to content

Latest commit

 

History

History
47 lines (32 loc) · 2.42 KB

the-sublayertransfrom-property.md

File metadata and controls

47 lines (32 loc) · 2.42 KB

sublayerTransform属性

如果有多个视图或者图层,每个都做3D变换,那就需要分别设置相同的m34值,并且确保在变换之前都在屏幕中央共享同一个position,如果用一个函数封装这些操作的确会更加方便,但仍然有限制(例如,你不能在Interface Builder中摆放视图),这里有一个更好的方法。

CALayer有一个属性叫做sublayerTransform。它也是CATransform3D类型,但和对一个图层的变换不同,它影响到所有的子图层。这意味着你可以一次性对包含这些图层的容器做变换,于是所有的子图层都自动继承了这个变换方法。

相较而言,通过在一个地方设置透视变换会很方便,同时它会带来另一个显著的优势:灭点被设置在容器图层的中点,从而不需要再对子图层分别设置了。这意味着你可以随意使用positionframe来放置子图层,而不需要把它们放置在屏幕中点,然后为了保证统一的灭点用变换来做平移。

我们来用一个demo举例说明。这里用Interface Builder并排放置两个视图(图5.12),然后通过设置它们容器视图的透视变换,我们可以保证它们有相同的透视和灭点,代码见清单5.6,结果见图5.13。

图5.12

图5.12 在一个视图容器内并排放置两个视图

清单5.6 应用sublayerTransform

@interface ViewController ()

@property (nonatomic, weak) IBOutlet UIView *containerView;
@property (nonatomic, weak) IBOutlet UIView *layerView1;
@property (nonatomic, weak) IBOutlet UIView *layerView2;

@end

@implementation ViewController

- (void)viewDidLoad
{
    [super viewDidLoad];
    //apply perspective transform to container
    CATransform3D perspective = CATransform3DIdentity;
    perspective.m34 = - 1.0 / 500.0;
    self.containerView.layer.sublayerTransform = perspective;
    //rotate layerView1 by 45 degrees along the Y axis
    CATransform3D transform1 = CATransform3DMakeRotation(M_PI_4, 0, 1, 0);
    self.layerView1.layer.transform = transform1;
    //rotate layerView2 by 45 degrees along the Y axis
    CATransform3D transform2 = CATransform3DMakeRotation(-M_PI_4, 0, 1, 0);
    self.layerView2.layer.transform = transform2;
}

图5.13

图5.13 通过相同的透视效果分别对视图做变换