高级动画学习心得笔记(四)视觉效果

4.1圆角

CALayer有一个叫做cornerRadius的属性控制着图层角的曲率,它是一个浮点数,默认为0(直角)。默认情况下,这个属性值只影响背景颜色而不影响背景图片或是子图层。不过,如果把masksToBounds设置为YES的话,图层里面所有的东西都会被裁剪。

单独控制每个图层的圆角曲率也是可以的。如果想创建部分圆角部分直角的图层或试图时,你可能需要一些不同的方法,比如使用一个图层蒙版或者是CAShapeLayer

4.2图层边框

borderWidth:边框宽度,浮点型,默认为0.

borderColor:边框颜色,CGColorRef类型,默认为黑色。OC语法中,CGColorRef即使是强引用也只能通过assign来修饰

这两个属性共同定义了图层边的绘制样式,这条线使用stoke方式沿着图层的bounds绘制,同事也包含图层的角

边框是绘制在图层边界里面的,而且在所有子内容之前,也在子图层之前。也就是说,无论子图层或者子视图的内容是否超出边界,或者是寄宿图在透明区域有一个透明蒙版,边框仍然会沿着图层的边界绘制出来,并且显示在用户视角的最前方

4.3阴影

4.3.1阴影的各个要素

阴影往往可以达到图层深度暗示的效果。也能够用来强调正在显示的图层和优先级(比如说一个在其他视图之前的弹出框),不过有时候他们只是单纯的装饰目的。

shadowOpacity:取值范围在0.0(不可见)和1.0(完全不透明)之前的浮点数。给shadowOpacity一个大于默认值(默认值为0)的值,阴影就可以显示在任意图层之下。如果设置为1.0,将会显示一个有轻微模糊的黑色阴影稍微在图层之上。

shadowColor:控制阴影的颜色,和borderColor和backgroundColor一样,它的类型也是CGColorRef。阴影默认为黑色,也可以设置其它颜色

shadowOffset:控制阴影的方向和距离,它是一个CGSize类型的值,宽度控制阴影横向的位移,高度控制纵向的位移。shadowOffset默认值为{0,-3},即阴影相对于Y轴有3个点的向上位移。在Mac OS上,由于Y轴和ios是颠倒的,,虽然默认值仍然是{0,-3},但它是向下偏移3个点的。苹果更倾向于用户界面的阴影是垂直向下的,所以在ios上把阴影宽度设置为0,然后高度设置为正值是符合苹果审美的做法。

shadowRadius:控制阴影的模糊度,默认为0,当它的值是0的时候,阴影和视图一样有一个非常确定的边界线,当值越来越大的时候,边界线看上去就会越来越模糊和自然。苹果自家的应用设计更偏向于自然的阴影,所以一个非零值是更好的选择。

4.3.2阴影裁剪

和图层边框不同,图层的阴影继承自内容的外形,而不是根据边界和角半径来确定。为了计算出阴影的形状,Core Animation会将寄宿图(包括子视图,如果有的话)考虑在内,然后通过这些来完美他陪图层形状从而创建一个阴影

当阴影和裁剪扯上关系的时候就有一个头疼的问题:阴影通常就是在layer的边界之外,如果设置了masksToBounds为YES的话,所有从图层中凸出来的内容都会被裁剪掉。

如果想沿着内容裁切,但是又需要有阴影的话,你需要用到两个图层:一个只画阴影的空的外图层,和一个用masksToBounds裁剪内容的内涂层。

4.3.3 shadowPath属性

通常情况下,阴影是从图层内容的形状继承而来,但是实时计算阴影也是非常消耗资源的,尤其是图层有多个子图层,每个图层还有一个有透明效果的寄宿图的时候

如果事先知道阴影形状回事什么样子的,可以通过制定一个shadowPath来提高性能,shadowPath是一个CGPathRef类型(一个指向CGPath的指针)。CGPath是一个Core Graphics对象,用来指定任意的矢量图形。我们可以通过这个属性单独于图层形状之外指定阴影的形状。

如果是一个矩形或者是圆,用CGPath会相当简单明了。但是如果是更加负责一点的图形,UIBezierPath类会更合适,它是一个由UIKit提供的在CGPath基础上的OC包装类

4.4 图层蒙版

mask:CALayer类型,它可以让你以编码的方式动态的生成蒙版,也不能让子图层或子视图裁剪成同样的情况。

它有和其它图层一样的绘制和布局属性。

它类似一个子图层,相对于父图层(即拥有该属性的图层)布局,但是它却不是一个普通的子图层,mask图层定义了父图层的部分可见区域。

mask图层的color属性是无关紧要的,真正重要的是图层的轮廓。mask图层实心的部分会被保留下来,其它的则会被抛弃。(Layer的透明度决定了Layer内容是否可以显示,非透明的内容和背景可以显示,透明的则无法显示.)

如果mask图层比父图层小,只有在mask图层里面的内容才是它关心的,除此以外的一切都会被隐藏起来。

mask真正厉害的地方在于蒙版图不局限于静态图。任何有图层构成的都可以作为mask属性,这意味着你的蒙版可以通过代码甚至是动画实时生成。

4.5拉伸过滤

minificationFilter 用于内容减小时候的拉伸过滤算法

magnificationFilter 用于内容增大时候的拉伸过滤算法

它们都是NSString类型,但是值都是Scaling Filters 常量中选取,有以下三种:

.kCAFilterLinear 双线性滤波算法,它在大多数情况下表现良好。双线性滤波算法通过对多个像素取样最终生成新的值,得到一个平滑的表现不错的拉伸。但是当放大倍数比较大的时候图片就模糊不清了。

.kCAFilterNearest 最近过滤算法,这是一种比较武断的方法。这个算法就是取样最近的单像素点而不管其它的颜色。这样做非常快,也不会使图片模糊,但是,最明显的效果就是,会是的压缩图片更糟,图片放大之后也显得块状或是马赛克严重。对于比较小的图或者是差异特别明显,极少斜线的大图,最近过滤算法会保留这种差异明显的特质以呈现更好的结果。但是对于大多数的图尤其是有很多斜线或是曲线轮廓的图片来说,最近过滤算法会导致更差的结果。换句话说,线性过滤保留了形状,最近过滤则保留了像素的差异。

.kCAFilterTrilinear 三线性滤波算法,和kCAFilterLinear非常类似,大部分情况下二者都看不出来有什么差别。但是,较双线性滤波算法而言,三线性滤波算法存储了多个大小情况下的图片(也叫多重贴图),并三维取样,同时结合大图和小图的存储进而得到最后的结果。这个方法的好处在于能够从一系列已经接近于最终大小的图片中得到想要的结果,也就是说不需要对很多像素同步取样。这不仅提高了性能,也避免了小概率因舍入错误引起的取样失灵的问题。

minificationFilter和magnificationFilter属性的默认值都是kCAFilterLinear。

4.6组透明

opacity:确定图层的透明度,对应于UIView的alpha属性,这两个属性都是影响子层级的。也就是说,如果你给一个图层设置了opacity属性,那它的子图层都会受此影响。

ios常常把一个控件的alpha值设置为0.5以使其看上去呈现为不可用状态。

当你显示一个50%透明度的图层时,图层的每个像素都会一半显示自己的颜色,另一半显示图层下面的颜色。但是如果图层包含一个同样50%透明的子图层时,你所看到的视图,50%来自子视图,25%来自图层本身的颜色,另外25%则来自背景色。

理想状况下,当你设置了一个图层的透明度,你希望它包含的整个图层树像一个整体一样的透明效果,你可以通过设置Info.plist文件中的UIViewGroupOpacity为YES来达到这个效果,但是这个设置会影响到整个应用.

另外一个方法就是,设置CALayer的shouldRasterize属性来实现组透明的效果,如果它被设置为YES,在应用透明度之前,图层及其子图层都会被整合成一个整体的图片,这样就没有透明度混合的问题了。

为了启动shouldRasterize属性,我们设置了图层的rasterizationScale属性。默认情况下,所有图层拉伸都是1.0,所以如果你使用了shouldRasterize属性,就得确保设置了rasterizationScale属性去匹配屏幕,以防止出现Retina屏幕像素化的问题。

你可能感兴趣的:(高级动画学习心得笔记(四)视觉效果)