iOS Core Animation - Advanced Te

2021-01-04  本文已影响0人  优质胡萝北

变换

仿射变换

- (void)viewDidLoad {
    [super viewDidLoad];
    //create a new transform
    CGAffineTransform transform = CGAffineTransformIdentity; 
    //scale by 50%
    transform = CGAffineTransformScale(transform, 0.5, 0.5);
    //rotate by 30 degrees
    transform = CGAffineTransformRotate(transform, M_PI / 180.0 * 30.0);
    //translate by 200 points
    transform = CGAffineTransformTranslate(transform, 200, 0);
    //apply transform to layer
    self.layerView.layer.affineTransform = transform;
}

3D变换

透视效果

- (void)viewDidLoad {
    [super viewDidLoad];
    //create a new transform
    CATransform3D transform = CATransform3DIdentity;
    //apply perspective
    transform.m34 = - 1.0 / 500.0;
    //rotate by 45 degrees along the Y axis
    transform = CATransform3DRotate(transform, M_PI_4, 0, 1, 0);
    //apply to layer
    self.layerView.layer.transform = transform;
}

灭点

sublayerTransform属性

- (void)viewDidLoad {
    [super viewDidLoad];
    //apply perspective transform to container
    //容器视图变换,perspective将会影响layerView1和layerView2
    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;
}

图层的背面

专用图层

CALayer类具有一些非常有用的绘图和动画功能。但Core Animation不仅作用于图片和颜色,CALayer拓展了其他一些专用于某种功能的子类,以增强Core Animation的绘图能力。这里学习总结了几个常用的专用图层,其他的仅作了解

CAShapeLayer - 形状图层

// 利用CAShapeLayer新建图层绘制一个火柴人
- (void)viewDidLoad {
  [super viewDidLoad];
  //create path
  UIBezierPath *path = [[UIBezierPath alloc] init];
  [path moveToPoint:CGPointMake(175, 100)];
  
  [path addArcWithCenter:CGPointMake(150, 100) radius:25 startAngle:0 endAngle:2*M_PI clockwise:YES];
  [path moveToPoint:CGPointMake(150, 125)];
  [path addLineToPoint:CGPointMake(150, 175)];
  [path addLineToPoint:CGPointMake(125, 225)];
  [path moveToPoint:CGPointMake(150, 175)];
  [path addLineToPoint:CGPointMake(175, 225)];
  [path moveToPoint:CGPointMake(100, 150)];
  [path addLineToPoint:CGPointMake(200, 150)];

  //create shape layer
  CAShapeLayer *shapeLayer = [CAShapeLayer layer];
  shapeLayer.strokeColor = [UIColor redColor].CGColor;
  shapeLayer.fillColor = [UIColor clearColor].CGColor;
  shapeLayer.lineWidth = 5;
  shapeLayer.lineJoin = kCALineJoinRound;
  shapeLayer.lineCap = kCALineCapRound;
  shapeLayer.path = path.CGPath;
  //add it to our view
  [self.containerView.layer addSublayer:shapeLayer];
}
- (void)addRoundedCorners:(UIRectCorner)corners radius:(CGFloat)radii{
    
    UIBezierPath* rounded = [UIBezierPath bezierPathWithRoundedRect:self.bounds byRoundingCorners:corners cornerRadii:CGSizeMake(radii, radii)];
    CAShapeLayer* shape = [[CAShapeLayer alloc] init];
    [shape setPath:rounded.CGPath];
    
    self.layer.mask = shape;
}

这么做有两个问题,一是当我们同时需要创建指定圆角和阴影时,不可避免要添加一个新的Container图层;二是动态修改frame.size时,蒙版路径并不会更新(准确说pathRect就是初始bounds值)

在书中提出【我们可以把CAShapeLayer作为视图的宿主图层,而不是添加一个子视图】。经过实验,一个可行的方案是,我们重写UIView的+layerClass方法,返回指定图层类CAShapeLayer.class,并在图层布局的时候指定path,注意,如果要指定CAShapeLayer背景图层着色,要使用fillColor属性而不能直接写backgroundColor

+ (Class)layerClass{
    return CAShapeLayer.class;
}

- (void)layoutSublayersOfLayer:(CALayer *)layer{
    [super layoutSublayersOfLayer:layer];
    UIBezierPath *path = [UIBezierPath bezierPathWithRoundedRect:self.bounds byRoundingCorners:_corners cornerRadii:CGSizeMake(10, 10)];
    _shapeLayer.path = path.CGPath;
}

- (instancetype)initWithFrame:(CGRect)frame{
    self = [super initWithFrame:frame];
    if (self) {
        //custom layer
        _shapeLayer = (CAShapeLayer *)self.layer;
        _corners = UIRectCornerTopRight | UIRectCornerBottomRight | UIRectCornerBottomLeft;
    }
    return self;
}

CAGradientLayer - 渐变图层

- (void)viewDidLoad {
  [super viewDidLoad];
  //create gradient layer and add it to our container view
  CAGradientLayer *gradientLayer = [CAGradientLayer layer];
  gradientLayer.frame = self.containerView.bounds;
  [self.containerView.layer addSublayer:gradientLayer];

  //set gradient colors
  gradientLayer.colors = @[(__bridge id)[UIColor redColor].CGColor, (__bridge id)[UIColor blueColor].CGColor];

  //set gradient start and end points
  gradientLayer.startPoint = CGPointMake(0, 0);
  gradientLayer.endPoint = CGPointMake(1, 1);
}

CAReplicatorLayer - 重复图层

CAEmitterLayer - 粒子图层

上一篇 下一篇

猜你喜欢

热点阅读