最近在做iOS开发的时候,遇到这样的需求:需要开发一个高度自适应的控件,背景使用图案平铺,控件下方两个角为圆角,控件的下边有5像素宽的阴影。具体如图所示:
方案A
在做这个需求时首先想到是用colorWithPatternImage
来平铺图片,然后使用CALayer添加阴影。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
|
不过这样做的严重缺陷是阴影被裁切掉了。
方案B
所以考虑使用Quartz的CGContextDrawTiledImage
来平铺背景,使用layer制造阴影。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 |
|
这样做虽然可以大概的实现需求,不过阴影的宽度不可控制。
方案C
于是我尝试使用Quartz的CGContextSetShadowWithColor
来绘制阴影,但是怎么绘制阴影呢?使用CGContextDrawTiledImage
平铺背景时会占满指定的区域,这样也有没有了绘制阴影的空间。
在stackoverflow搜索了一圈,有人建议先使用固定色填充圆角区域,再在这个区域平铺图片。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 |
|
这个方案比上个方案好了很多,不过细心的人可能会发现圆角的阴影有深色的锯齿,不够协调。原因是阴影是根据固定色生成的,在处理边界过度时是从固定色过度来的。
方案D
那有没有办法让阴影根据图片来生成呢?我想到了CGContextDrawImage
方法。先在一个特殊的context
生成平铺图,然后在当前的context
使用CGContextDrawImage
来绘制图片,这样绘制图片的同时会产生相应的阴影。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 |
|
结语
作为初学者,对Quartz也只是一知半解。尝试过程中发现绘制的时候一定要注意顺序,否则会出现各种奇怪的问题。Quartz是个强大东西,要好好利用还需跟多的尝试。
另附上本文的源代码:https://github.com/ohsc/CodeBox-of-Cocoa/tree/master/RoundedCornerImageWithShadow
四个方案运行效果图: