美文网首页iOS常用
iOS 圆角和阴影的一点采坑体会

iOS 圆角和阴影的一点采坑体会

作者: 小白猿 | 来源:发表于2020-06-08 13:15 被阅读0次

    前提

    iOS 对于UIView 圆角 和 阴影的设置一般都给予对layer的操作,通常做法为

    • 圆角
    UIView *view  = [UIView alloc] init];
    view.layer.masksToBounds = YES;
    view.layer.cornerRadius = 2;
    
    • 阴影
    view.layer.shadowOpacity = 1;//阴影透明度,默认0
    view.layer.shadowRadius = 5;
    view.layer.shadowOffset = CGSizeZero;
    view.layer.shadowColor = [[UIColor redColor] CGColor];
    

    二者的不能并存的原因是 layer.masksToBounds,这个属性会对超出视图本身的区域进行裁切,阴影会被裁减掉,所以针对此种方式,查了各种资料,比较通常的做法是,使用两个View 或者 使用 一个 view 一个 layer,后者我还在研究中,前者经过实际写代码过程中也不是一帆风顺,遇到了一些小问题,再次记录下。

    具体过程

    用两层view实现圆角和阴影的思路很简单,就是使用父子两层容器,父容器负责阴影,子容器负责切圆角,然后子容器的frame 设置为父容器的bounds。

    但是在代码开发过程中发现,父容器的阴影没有问题,但是子容器的圆角始终无法出现,然后尝试了很多办法都不行,后来我给子容器设置了特殊背景色去排查错误的时候,发现子容器是有圆角的,但是设置为何父容器一样的颜色就不行,后来发现子是因为子容器的背景色和父容器一样的时候,圆角就显示不出不来了,如图【黑色是子容器,蓝色是父容器】

    image.png
    后来我尝试将父容器的颜色设置为 clearColor,结果阴影也没了,最终的解决方案:父容器去掉背景色(不是设置为clearColor,就是不再写backgroundColor),子容器必须设置背景色。

    关于layer的实现方案,在自己的采坑过程中,依旧有些问题,后续进行补充

    2020 6月10日续

    今天在看同事代码的时候,也有阴影和圆角,所以效果看下具体的实现效果。再次进行记录下,实现方案要略简单一些,但是要也有些注意的地方

    总是思路还是父子两个容器,不同的是子容器不需要再负责圆角,圆角和阴影都由父容器去控制,具体怎么做呢,看下下面的代码

    UIView *shadowView = [[UIView alloc] initWithFrame:CGRectMake(100, 200, 200, 200)];
    [self.view addSubview: shadowView];
    shadowView.backgroundColor = [UIColor whiteColor];
    shadowView.layer.shadowColor = [UIColor darkGrayColor].CGColor;
    shadowView.layer.shadowOffset = CGSizeZero;
    shadowView.layer.shadowOpacity = 1;
    // 阴影设置圆角
    shadowView.layer.cornerRadius = 5;
    

    我们对代码父容器的阴影设置圆角,子控件不在设置裁切,但是frame要做相应的修改,此处圆角半径为5,那么我们子控件在上一种方案是宽高和父容器一直,这样必然会遮住阴影,所以我们要根据圆角的大小,对子控件的宽高进行缩小宽高都要减小 2 倍的半径

    UIView *layerView = [[UIView alloc] initWithFrame:CGRectMake(5,5, 190, 190)];
    layerView.backgroundColor = [UIColor whiteColor];
    [shadowView addSubview:layerView];
    

    效果为


    image.png

    为了看下实际效果,我们子控件设置为别的颜色


    image.png

    此种方法的核心点在于

    • 不用刻意考虑子背景色的问题,已经切角和阴影都交给父控件去处理。
    • 这里其实有个知识点,就是我们没有使用masksToBounds,使用了cornerRadius就可以起到圆角的效果。这是因为cornerRadius仅对主layer起作用,但是子控件等是放在主layer的contents属性里去显示,所以必须进行裁剪才能起到作用。这里巧妙的御用了子控件缩放,不超出父容器的size,确实是个不错的办法

    总结

    第二种方案看似是很简单,那么是不是第一种方案就没有用武之地了呢?很明显不是!第二种方式如果对于要求子控件和父控件尺寸必须一致,不能有太多留白的时候,就不能起到效果了,第一种可以做到父子空间完全贴合。所以可以看具体的场景进行区分

    相关文章

      网友评论

        本文标题:iOS 圆角和阴影的一点采坑体会

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