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,它定義了一個固定的邊框和一個在圖層上可拉伸的區(qū)域。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協(xié)議,當CALayer需要一個內容特定的信息時,就會從協(xié)議中請求。
    
    //當需要被重繪時,CALayer會請求它的代理給他一個寄宿圖來顯示。它通過調用下面這個方法做到的:
    //(void)displayLayer:(CALayerCALayer *)layer;
    //如果代理不實現-displayLayer:方法,CALayer就會轉而嘗試調用下面這個方法:
    //- (void)drawLayer:(CALayer *)layer inContext:(CGContextRef)ctx;
    
    //在調用這個方法之前,CALayer創(chuàng)建了一個合適尺寸的空寄宿圖(尺寸由bounds和contentsScale決定)和一個Core Graphics的繪制上下文環(huán)境,為繪制寄宿圖做準備,他作為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);
}
*/
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

友情鏈接更多精彩內容