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

前提

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 圆角和阴影的一点采坑体会)