iOS 动画 第二章 寄宿图

[self liveInImage];
- (void)liveInImage {
    UIView *layerV = [[UIView alloc] init];
    layerV.frame = CGRectMake(20.0f, 20.0f, 200.0f, 300.0f);
    layerV.backgroundColor = [UIColor blackColor];
    [self.view addSubview:layerV];
    
    /*
    //contents属性:如果你给contents赋的不是CGImage,那么你得到的图层将是空白的
    //你真正要赋值的类型应该是CGImageRef,它是一个指向CGImage结构的指针。UIImage有一个CGImage属性,它返回一个"CGImageRef",如果你想把这个值直接赋值给CALayer的contents,那你将会得到一个编译错误。因为CGImageRef并不是一个真正的Cocoa对象,而是一个Core Foundation类型。
    //layer.contents = (__bridge id)image.CGImage;//如果你没有使用ARC(自动引用计数),你就不需要__bridge这部分。但是,你干嘛不用ARC?!
    
    UIImage *image = [UIImage imageNamed:@"Meal"];
    layerV.layer.contents = (__bridge id)image.CGImage;
    
    //contentGravity:CALayer与contentMode对应的属性叫做contentsGravity, 但是它是一个NSString类型
    //layerV.layer.contentsGravity = kCAGravityResizeAspect;
    
    //contentsScale:属性定义了寄宿图的像素尺寸和视图大小的比例,默认情况下它是一个值为1.0的浮点数.
    //如果你只是单纯地想放大图层的contents图片,你可以通过使用图层的transform和affineTransform属性来达到这个目的.
    //UIView有一个类似功能但是非常少用到的contentScaleFactor属性。
    layerV.layer.contentsGravity = kCAGravityCenter;
    layerV.layer.contentsScale = image.scale;
    
    //maskToBounds:UIView有一个叫做clipsToBounds的属性可以用来决定是否显示超出边界的内容,CALayer对应的属性叫做masksToBounds
    layerV.layer.masksToBounds = YES;
    
    //contentsRect:CALayer的contentsRect属性允许我们在图层边框里显示寄宿图的一个子域。
    //它使用了单位坐标,单位坐标指定在0到1之间,是一个相对值(像素和点就是绝对值)。默认的contentsRect是{0, 0, 1, 1}
    //contentsRect在app中最有趣的地方在于一个叫做image sprites(图片拼合)的用法。
    UIView *coneView = [[UIView alloc] init];
    coneView.frame = CGRectMake(20.f, 20.0f, 50.0f, 50.0f);
    [self.view addSubview:coneView];
    [self addSpriteImage:image ContentRect:CGRectMake(0, 0, 0.5, 0.5) toLayer:coneView.layer];
    
    UIView *shipView = [[UIView alloc] init];
    shipView.frame = CGRectMake(100.0f, 30.0f, 50.0f, 50.0f);
    [self.view addSubview:shipView];
    [self addSpriteImage:image ContentRect:CGRectMake(0.5, 0, 0.5, 0.5) toLayer:shipView.layer];

    
    UIView *iglooView = [[UIView alloc] init];
    iglooView.frame = CGRectMake(60.0f, 100.0f, 50.0f, 50.0f);
    [self.view addSubview:iglooView];
    [self addSpriteImage:image ContentRect:CGRectMake(0, 0.5, 0.5, 0.5) toLayer:iglooView.layer];

    
    UIView *anchorView = [[UIView alloc] init];
    anchorView.frame = CGRectMake(120.0f, 100.0f, 50.0f, 50.0f);
    [self.view addSubview:anchorView];
    [self addSpriteImage:image ContentRect:CGRectMake(0.5, 0.5, 0.5, 0.5) toLayer:anchorView.layer];
    
    //contentsCenter:contentsCenter其实是一个CGRect,它定义了一个固定的边框和一个在图层上可拉伸的区域。contentsCenter是{0, 0, 1, 1}
    UIButton *btn1 = [UIButton buttonWithType:UIButtonTypeCustom];
    btn1.frame = CGRectMake(20.0f, 200.0, 200.0f, 200.0f);
    [self.view addSubview:btn1];
    [self addStretchableImage:image contentCenter:CGRectMake(0.0, 0.0, 0.5, 0.5) toLayer:btn1.layer];
    
    UIButton *btn2 = [UIButton buttonWithType:UIButtonTypeCustom];
    btn2.frame = CGRectMake(120.0f, 400.0, 200.0f, 200.0f);
    [self.view addSubview:btn2];
    [self addStretchableImage:image contentCenter:CGRectMake(0.25, 0.25, 0.5, 0.5) toLayer:btn2.layer];
     */
    
    //Custome Drawing
    //可以直接用Core Graphics直接绘制寄宿图。能够通过继承UIView并实现-drawRect:方法来自定义绘制。
    //如果UIView检测到-drawRect: 方法被调用了,它就会为视图分配一个寄宿图,这个寄宿图的像素尺寸等于视图大小乘以 contentsScale的值。
    //-drawRect:方法里面的代码利用Core Graphics去绘制一个寄宿图,然后内容就会被缓存起来直到它需要被更新
    
    //CALayer有一个可选的delegate属性,实现了CALayerDelegate协议,当CALayer需要一个内容特定的信息时,就会从协议中请求。
    
    //当需要被重绘时,CALayer会请求它的代理给他一个寄宿图来显示。它通过调用下面这个方法做到的:
    //(void)displayLayer:(CALayerCALayer *)layer;
    //如果代理不实现-displayLayer:方法,CALayer就会转而尝试调用下面这个方法:
    //- (void)drawLayer:(CALayer *)layer inContext:(CGContextRef)ctx;
    
    //在调用这个方法之前,CALayer创建了一个合适尺寸的空寄宿图(尺寸由bounds和contentsScale决定)和一个Core Graphics的绘制上下文环境,为绘制寄宿图做准备,他作为ctx参数传入。
    //create sublayer
    CALayer *blueLayer = [CALayer layer];
    blueLayer.frame = CGRectMake(50.f, 50.0f, 100.0f, 100.0f);
    blueLayer.backgroundColor = [[UIColor blueColor] CGColor];
    
    //set controller as layer delegate
    blueLayer.delegate = self;
    
    //ensure that layer backing image uses correct scale
    blueLayer.contentsScale = [UIScreen mainScreen].scale;
    
    //add layer to our view
    [layerV.layer addSublayer:blueLayer];
    
    //force layer to redraw
    [blueLayer display];
}

- (void)addSpriteImage:(UIImage *)image ContentRect:(CGRect )rect toLayer:(CALayer *)layer {
    layer.contents = (__bridge id)image.CGImage;
    layer.contentsGravity = kCAGravityResizeAspect;
    layer.contentsRect = rect;
}

- (void)addStretchableImage:(UIImage *)image contentCenter:(CGRect )rect toLayer:(CALayer *)layer {
    layer.contents = (__bridge id)image.CGImage;
    layer.contentsCenter = rect;
}

#pragma mark CALayerDelegate
/*
 - (void)drawLayer:(CALayer *)layer inContext:(CGContextRef)ctx {
    //draw a thick red circle
    CGContextSetLineWidth(ctx, 10.0f);
    CGContextSetStrokeColorWithColor(ctx, [UIColor redColor].CGColor);
    CGContextStrokeEllipseInRect(ctx, layer.bounds);
}
*/

你可能感兴趣的:(iOS 动画 第二章 寄宿图)