美文网首页上海快风信息科技有限公司将来跳槽用ios
容易忽略的那些小点总结 (六) —— CALayer相关(五)

容易忽略的那些小点总结 (六) —— CALayer相关(五)

作者: 刀客传奇 | 来源:发表于2018-01-22 23:40 被阅读55次

    版本记录

    版本号 时间
    V1.0 2018.01.22

    前言

    在苹果的API文档中,有很多属性和方法我们用的不是很多,所以很容易忽略和出错,下面我就用这一个专题专门说一些不常用的API接口,下面开始。感兴趣的可以参考前面几篇文章。
    1. 容易忽略的那些小点总结 (一) —— UIView UIViewTintAdjustmentMode相关(一)
    2. 容易忽略的那些小点总结 (二) —— CALayer相关(一)
    3. 容易忽略的那些小点总结 (三) —— CALayer相关(二)
    4. 容易忽略的那些小点总结 (四) —— CALayer相关(三)
    5. 容易忽略的那些小点总结 (五) —— CALayer相关(四)

    edgeAntialiasingMask

    位掩码用于定义接收器边缘如何光栅化,还是先看一下其API文档。

    /* Defines how the edges of the layer are rasterized. For each of the
     * four edges (left, right, bottom, top) if the corresponding bit is
     * set the edge will be antialiased. Typically this property is used to
     * disable antialiasing for edges that abut edges of other layers, to
     * eliminate the seams that would otherwise occur. The default value is
     * for all edges to be antialiased. */
    
    定义图层的边缘如何被光栅化。 对于四个边(左,右,下,上)中的每一个,如果相应的
    位被设置,边将被反锯齿。 通常,此属性用于禁用对邻接其他图层边缘的边缘进行抗锯齿,
    以消除否则会出现的接缝。 默认值是所有的边缘都是反锯齿的。
    
    @property CAEdgeAntialiasingMask edgeAntialiasingMask;
    

    这个是一个枚举,我们看看都可以取哪些值。

    /* Bit definitions for `edgeAntialiasingMask' property. */
    
    typedef NS_OPTIONS (unsigned int, CAEdgeAntialiasingMask)
    {
      kCALayerLeftEdge      = 1U << 0,      /* Minimum X edge. */
      kCALayerRightEdge     = 1U << 1,      /* Maximum X edge. */
      kCALayerBottomEdge    = 1U << 2,      /* Minimum Y edge. */
      kCALayerTopEdge       = 1U << 3,      /* Maximum Y edge. */
    };
    

    还可以这么理解:

    • 此属性指定图层的哪些边是反锯齿的,并且是CAEdgeAntialiasingMask中定义的常量的组合。 您可以分别为每个边(顶部,左侧,底部,右侧)启用或禁用抗锯齿功能。 默认情况下,对所有边缘启用反锯齿。

    • 通常情况下,您将使用此属性来禁用与其他图层边缘邻接的抗锯齿功能,以消除否则会出现的接缝。

    • Layer的edgeAntialiasingMask属性并不能有效抗锯齿,只需要在图片边缘加入1个像素的透明区域就可以完美实现图片抗锯齿了。


    allowsEdgeAntialiasing

    这是一个布尔值,指示是否允许图层执行边缘抗锯齿。在使用view的缩放的时候,layer.border.width随着view的放大,会出现锯齿化的问题,解决这个问题需要设置这个属性。self.layer.allowsEdgeAntialiasing = YES;还是先看一下API文档。

    /* When true this layer is allowed to antialias its edges, as requested
     * by the value of the edgeAntialiasingMask property.
     *
     * The default value is read from the boolean UIViewEdgeAntialiasing
     * property in the main bundle's Info.plist. If no value is found in
     * the Info.plist the default value is NO. */
    
    如果为true,则允许按照edgeAntialiasingMask属性值的要求对该图层进行抗锯齿处理。 
    默认值是从主包的Info.plist中的布尔值UIViewEdgeAuthoriasing属性中读取的。 如果在
    Info.plist中找不到值,则默认值为NO。
    
    @property BOOL allowsEdgeAntialiasing;
    

    还有几个问题:

    • 在这个属性allowsEdgeAntialiasing出现之前,是如何抗锯齿的呢,一般是添加一个像素的透明边。具体代码可以参考。
    - (UIImage *)antiAlias
    {
        CGFloat border = 1.0f;
        CGRect rect = CGRectMake(border, border, self.size.width-2*border, self.size.height-2*border);
        UIImage *img = nil;
         
        UIGraphicsBeginImageContext(CGSizeMake(rect.size.width,rect.size.height));
        [self drawInRect:CGRectMake(-1, -1, self.size.width, self.size.height)];
        img = UIGraphicsGetImageFromCurrentImageContext();
        UIGraphicsEndImageContext();
         
        UIGraphicsBeginImageContext(self.size);
        [img drawInRect:rect];
        UIImage* antiImage = UIGraphicsGetImageFromCurrentImageContext();
        UIGraphicsEndImageContext();
         
        return antiImage;
    }
    

    具体效果如下所示

    • 下面对比一下不做任何处理、透明边处理和属性allowsEdgeAntialiasing设置三种情况下性能的差别。

    上图结果表明,allowsEdgeAntialiasing的性能还是比透明边的方式要差一点。


    maskedCorners

    这是一个枚举值,是iOS11.0新出的属性

    看一下API文档

    /* Defines which of the four corners receives the masking when using
     * `cornerRadius' property. Defaults to all four corners. */
    
    当使用cornerRadius属性时,定义四个角中的哪一个接收到遮罩。 默认为全部四个角落。
    
    @property CACornerMask maskedCorners
      CA_AVAILABLE_STARTING (10.13, 11.0, 11.0, 4.0);
    

    下面我们就看一下这个枚举值都可以取哪些值

    /* Bit definitions for `maskedCorners' property. */
    
    typedef NS_OPTIONS (NSUInteger, CACornerMask)
    {
      kCALayerMinXMinYCorner = 1U << 0,
      kCALayerMaxXMinYCorner = 1U << 1,
      kCALayerMinXMaxYCorner = 1U << 2,
      kCALayerMaxXMaxYCorner = 1U << 3,
    };
    

    下面我们看一个例子

        UIView *view = [[UIView alloc] initWithFrame:CGRectMake(100.0, 200.0, 200.0, 100.0)];
        view.layer.backgroundColor = [UIColor blueColor].CGColor;
        view.layer.cornerRadius = 50.0;
        view.layer.maskedCorners = kCALayerMinXMinYCorner | kCALayerMaxXMinYCorner;
        [self.view addSubview:view];
    

    看一下效果示意图

    这个还是可动画的,下面还是看代码

    UIView *view = [[UIView alloc] initWithFrame:CGRectMake(100.0, 200.0, 200.0, 100.0)];
    view.layer.backgroundColor = [UIColor blueColor].CGColor;
    view.layer.cornerRadius = 50.0;
    view.layer.maskedCorners = kCALayerMinXMinYCorner | kCALayerMaxXMinYCorner;
    [self.view addSubview:view];
    
    [UIView animateWithDuration:7 delay:1.0 options:UIViewAnimationOptionCurveLinear animations:^{
        view.layer.cornerRadius = 0;
    } completion:nil];
    

    在iOS11.0之前圆角是不支持动画的。

    参考文章

    1. 图片变形的抗锯齿处理方法
    2. iOS11新特性——改善view圆角

    后记

    本篇已结束,后面更精彩~~~

    相关文章

      网友评论

        本文标题:容易忽略的那些小点总结 (六) —— CALayer相关(五)

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