美文网首页
CALayer的寄宿图

CALayer的寄宿图

作者: _涼城 | 来源:发表于2016-07-10 14:28 被阅读443次

        CALayer 有一个属性叫做contents,它可以直接在图层中放置一张图片

    @property contents

         尽管类型被定义为id,赋值CGImage,真正要赋值的类型应该是CGImageRef,它是一个指向CGImage结构的指针。

        事实上,contents这个奇怪的表现是由Mac OS的历史原因造成的。它之所以被定义为id类型,是因为在Mac OS系统上,这个属性对CGImage和NSImage类型的值都起作用。

        ARC下,要给图层的寄宿图赋值,可以按照以下这个方法:

        layer.contents = (__bridge id)image.CGImage;


        在我们为视图赋值图片的时候,有时会遇到图片为了适应视图而进行拉伸等改变。解决方法就是把contentMode属性设置成更合适的值,像这样:

           view.contentMode = UIViewContentModeScaleAspectFit;

           CALayer与contentMode对应的属性叫做contentsGravity

    @property contentsGravity            

          决定内容在图层的边界对齐方式, NSString 类型,默认值为kCAGravityResize,。

          kCAGravityCenter,水平和垂直居中

          kCAGravityTop,水平居中,垂直置顶边缘

          kCAGravityBottom,水平居中,垂直置底边缘

          kCAGravityLeft,水平居左边缘,垂直居中

          kCAGravityRight,水平居右边缘,垂直居中

          kCAGravityTopLeft,水平居左边缘,垂直置顶边缘   

          kCAGravityTopRight,水平居右边缘,垂直置顶边缘

          kCAGravityBottomLeft,水平居左边缘,垂直置底边缘

          kCAGravityBottomRight,水平居右边缘,垂直置底边缘   

          kCAGravityResize,调整大小以适应整个边界矩形

          kCAGravityResizeAspect,整大小以适应边界矩形,保持内容方面。如果内容不完全填充边 界矩形,则内容集中在部分轴上.

          kCAGravityResizeAspectFill。调整到完全填充边界矩形,同时仍然保留内容方面。内容集中在它超过的轴.


    @property contentsScale

          定义了寄宿图的像素尺寸和视图大小的比例,默认情况下它是一个值为1.0的浮点数

          contentsScale属性其实属于支持高分辨率(又称Hi-DPI或Retina)屏幕机制的一部分。它用来判断在绘制图层的时候应该为寄宿图创建的空间大小,和需要显示的图片的拉伸度(假设并没有设置contentsGravity属性)。

          这并不会对我们在使用kCAGravityResizeAspect时产生任何影响,因为它就是拉伸图片以适应图层而已,根本不会考虑到分辨率问题。但是如果我们把contentsGravity设置为kCAGravityCenter(这个值并不会拉伸图片),那将会有很明显的变化.

           当用代码的方式来处理寄宿图的时候,一定要记住要手动的设置图层的contentsScale属性.

            layer.contentsScale = [UIScreen mainScreen].scale;


    @property maskToBounds

         默认情况下,UIView仍然会绘制超过边界的内容或是子视图,在CALayer下也是这样的。UIView有一个叫做clipsToBounds的属性可以用来决定是否显示超出边界的内容,CALayer对应的属性叫做masksToBounds.


    UIImage *image = [UIImage imageNamed:@"素材"];

    //add it directly to our view's layer

    self.layerView.layer.contents = (__bridge id)image.CGImage;

    //正确地设置contentsGravity的值

    self.layerView.layer.contentsGravity = kCAGravityCenter;

    //set the contentsScale to match image

    self.layerView.layer.contentsScale = [UIScreen mainScreen].scale;;

    // 使用masksToBounds来修建图层内容

    self.layerView.layer.masksToBounds = YES;



    @property contentsRect

        CALayer的contentsRect属性允许我们在图层边框里显示寄宿图的一个子域,contentsRect不是按点来计算的,它使用了单位坐标,单位坐标指定在0到1之间,是一个相对值(像素和点就是绝对值)。所以他们是相对与寄宿图的尺寸的,默认的contentsRect是{0, 0, 1, 1}.

    iOS使用了以下的坐标系统:

    点 —— 在iOS和Mac OS中最常见的坐标体系。点就像是虚拟的像素,也被称作逻辑像素。在标准设备上,一个点就是一个像素,但是在Retina设备上,一个点等于2*2个像素。iOS用点作为屏幕的坐标测算体系就是为了在Retina设备和普通设备上能有一致的视觉效果。

    像素 —— 物理像素坐标并不会用来屏幕布局,但是仍然与图片有相对关系。UIImage是一个屏幕分辨率解决方案,所以指定点来度量大小。但是一些底层的图片表示如CGImage就会使用像素,所以你要清楚在Retina设备和普通设备上,他们表现出来了不同的大小。

    单位 —— 对于与图片大小或是图层边界相关的显示,单位坐标是一个方便的度量方式, 当大小改变的时候,也不需要再次调整。单位坐标在OpenGL这种纹理坐标系统中用得很多,Core Animation中也用到了单位坐标。

           contentsRect在app中最有趣的地方在于一个叫做image sprites(图片拼合)的用法。这个技术常用来指代载入拼合的图片,跟移动图片一点关系也没有。不过呢,你要是有兴趣在一些常见的app中使用拼合技术,那么一个叫做LayerSprites的开源库(https://github.com/nicklockwood/LayerSprites),它能够读取Cocos2D格式中的拼合图并在普通的Core Animation层中显示出来。


    #pragma mark - 3.图片拼合

    - (void)addSpriteImage:(UIImage *)image withContentRect:(CGRect)rect toLayer:(CALayer *)layer{

    //set image

    layer.contents = (__bridge id)image.CGImage;

    //scale contents to fit

    layer.contentsGravity = kCAGravityResizeAspect;

    //set contentsRect

    layer.contentsRect = rect;

    }

    - (void)imageSprites{

    UIImage *image = [UIImage imageNamed:@"2.7"];

    //set igloo sprite

    [self addSpriteImage:image withContentRect:CGRectMake(0, 0, 0.5, 0.5) toLayer:self.igloo.layer];

    //set cone sprite

    [self addSpriteImage:image withContentRect:CGRectMake(0.5, 0, 0.5, 0.5) toLayer:self.cone.layer];

    //set anchor sprite

    [self addSpriteImage:image withContentRect:CGRectMake(0, 0.5, 0.5, 0.5) toLayer:self.anchor.layer];

    //set spaceship sprite

    [self addSpriteImage:image withContentRect:CGRectMake(0.5, 0.5, 0.5, 0.5) toLayer:self.layerView.layer];

    }



    @property contentsCenter

          contentsCenter其实是一个CGRect,它定义了一个固定的边框和一个在图层上可拉伸的区域。

          默认情况下,contentsCenter是{0, 0, 1, 1},如果大小(由conttensGravity决定)改变了,那么寄宿图将会均匀地拉伸开。

          如果我们增加原点的值并减小尺寸。我们会在图片的周围创造一个边框。

    可以随意重设尺寸,边框仍然会是连续的。他工作起来的效果和UIImage里的-resizableImageWithCapInsets: 方法效果非常类似,只是它可以运用到任何寄宿图,甚至包括在Core Graphics运行时绘制的图形.

        contentsCenter可以在Interface Builder里面配置.


    #pragma mark - 设置可拉伸视图

    - (void)addStretchableImage:(UIImage *)image withContentCenter:(CGRect)rect toLayer:(CALayer *)layer

    {

    //set image

    layer.contents = (__bridge id)image.CGImage;

    //set contentsCenter

    layer.contentsCenter = rect;

    }

    - (void)setStretchableImage{

    UIImage *image = [UIImage imageNamed:@"素材"];

    //set button 1

    [self addStretchableImage:image withContentCenter:CGRectMake(0.25, 0.25, 0.5, 0.5) toLayer:self.layerView.layer];

    //set button 2

    [self addStretchableImage:image withContentCenter:CGRectMake(0.25, 0.25, 0.5, 0.5) toLayer:self.igloo.layer];

    }



    相关文章

      网友评论

          本文标题:CALayer的寄宿图

          本文链接:https://www.haomeiwen.com/subject/jmrdjttx.html