这是我看《iOS上的图形和动画处理》自己摘出来的笔记
iOS上有各种方式可以实现动画:在一个较低的层次提供了这种能力,在更高的层次也提供这种能力。我们可以获得的最高层次的动画能力是通过UIKit。可以不用特别复杂的方法就实现一些功能。
可以认为图形上下文(context)是一个图布,提供了大量的属性如画笔颜色、画笔粗细等。它是Cocoa Touch自动准备的。
View里面最重要的方法之一是drawRect:。Cocoa Touch在需要绘制这个视图时会自动调用此方法,并通过这个方法要求视图在图形上下文中绘制它的内容。
处理动画的框架:
・ UIKit:高层次的框架,允许开发人员创建视图、窗口、按钮和其他UI相关的组件。还将一些低级别的API引入到易于使用的高级别API中。
・ Quartz 2D:iOS上绘图的主要引擎;UIKit就使用Quartz。
・ Core Graphics:它支持上下文、加载图像、绘制图像,等等。
・ Core Animation:顾名思义,是一个帮肋开发者在iOS上实现动画的框架。
构造、设置和使用颜色:
UIColor实际上是UIKit对Core Graphics中CGColor的一个包装类。
检测颜色的组成部分步骤:
・ UIColor会返回一个CGColorRer类型的颜色对象,这是一个Core Graphics Color Reference对象;
・ 使用CGColorGetComponents函数获取颜色对象的各个分量;
・ 如果需要,使用CGColorGetNumberOfComponents函数来组成该颜色的颜色分量的数量。
绘制图像
加载图像的一些重要方法:
imageNamed:类方法
加载缓存(如果能够加载)图像。此方法的参数是应用束中图像的名字。
imageWithData:类方法
从一个NSData实例 中加载图像,NSData实例封装了图像数据并作为参数传入些方法。
initWithContentsOfFile:实例方法(用于初始化)
将传入的参数作为要载入的图像的路径并用它初始化图像对象。
注:这个路径应该是图像在应用束中的完整路径
initWithData:实例方法(用于初始化)
使用传入的NSData类型的参数初始化图像。该数据应该是一个有效的图像。
将UIImage类型的图像绘制到图形上下文的两种最简单的方式:
drawAtPoint:UIImage类的实例方法
按照图像的原始大小在给定的点绘制出图像。使用CGPointMake函数构造点。
drawInRect:UIImage类的实例方法
在给定的矩形区域内绘制图像。使用CGRectMake函数构造矩形区域。
绘制线条
路径是由屏幕上一个或一系列的点构成。路径和线条有很大区别,路径可以包含许多线条,但线条不能包含许多路径。
必须使用路径来绘制线条。指定起点和终点,然扣要求Core Graphics为你填充这个路径。Core Graphics会意识到你在这个路径上创造了线条,并使用你指定的颜色绘制路径。
eg.路径创建直线的步骤:
・ 为图形上下文选择一个颜色
・ 使用UIGraphicsGetCurrentContext函数获取图形上下文的句柄;
・ 使用CGContextMoveToPoint过程设置线条的起点;
・ 使用CGContextAddLineToPoint过程在图形上下文移动你的画笔来指定线条的终点;
・ 使用CGContextStrokePath过程创建你已设定好的路径。此过程将使用图形上下文已经设置的当前颜色来绘制路径。
可以使有CGContextSetLineWidth过程来设置线条的宽度。此过程每一个参数是你用来绘图的图形上下文,第二个参数是线条的宽度,用一个浮点数(CGFloat)表示。
你通过一个方法使用画笔之后,不管该方法绘制了什么,它都会让画笔的位置留在终点。
两条直线相交的点,称为连接。通过Core Graphics,你可以为相互连接的直线指定你想要的连接样式。使用CGContextSetLineJoin过程,它需要两个参数:一个是你需要设置连接样式的上下文,和连接的样式(CGLineJoin枚举类型):
kCGLineJoinMiter
尖角的连接样式,默认。
kCGLineJoinBevel
平角
kCGLineJoinRound
圆角
构造路径
路径属于正在绘制他们的图形一下文。路径没有边界(Boundary)或特定形状。但路径有边界框(Bounding boxes)。而路径的边界杠是包含了所有路径上的形状、点和其他已经绘制的对象的
最小矩形
。
常用方法:
CGPathCreateMutable函数
创建 一个类型CGMutablePathRef的可变路径,并返回其句柄。每次使用完这个路径,我们都应该为它做善后工作。
CGPathMoveToPoint过程
在路径上移动当前画笔的位置到一个点,这个点由CGPoint类型的参指定。
CGPathAddLineToPoint过程
从当前的画笔向指定位置(同样的由CGPoint类型的值指定)绘制线段。
CGContexAddPath过程
添加一个路径(由句柄指定)到图形上下文,准备用于绘图。
CGContextDrawPath过程
在图形上下文绘制给出的路径。
这其中有三个重要的方法:
kCGPathStroke:使用当前选定的描边颜色为路径描边。
kCGPathFill:使用当前选定的填充路径所包围的区域。
kCGPathFillStroke:组合描边和填充。使用当前选定的填充路径,使用选定的描边颜色绘制路径 的边缘。
CGPathRelease过程
释放为路径句柄分配的内存
CGPathAddRect过程
向路径添加一个矩形。。矩形的边界四一个CGRect结构体指定。
绘制矩形
传递给CGPathAddRects的参数是:
・ 将要添加矩形的路径的句柄;
・ 应用于这些矩形的变换(如果有的话);
・ CGRect矩形数组的引用;
・ 在前面的参数中传递的数组中矩形的数量。为了避免未知的行为,应该准确地传递你的数组的矩形数量,这非常重要
为形状添加阴影
在Core Graphics 中,我们可以使用下边两个过程对图形上下文应用阴影:
CGContextSetShadow过程
此过程将创建黑色或灰色的阴影,它接受三个参数:
CGContextSetShadowWithColor过程
除了最后一个参数,此过程接受与CGContextSetShadow一模一样的参数。第四个参数为CGColorRef,用于设置阴影的颜色。
为了避免阴影投射到不想设置阴影的图形上,应在用阴影效果之前保存图形上下文的状态,然后在需要删除阴影效果时恢复其状态。
一般说说,保存和恢复图形上下文的状态并不只限于阴影。恢复图形上下文的状态会恢复一切(填充颜色 、字体、线条粗细等)回到之前你为他们设置的值 。因此,如果你在此刻设置了填充和描边的颜色,这些颜色将被重设。
可以通过CGContextSaveGstate过程保存图形上下文的状态,通过CGContextRestoreGState过程恢复到以前的状态。
创建和绘制渐变
Core Graphics允许开发者创建两种类型的渐变:线性的和径向的
线性渐变以某种颜色从一个点开始,以另一种颜色在其它点结束(虽然它们的开始颜色和结束颜色可以相同,但这让它看上去不像一个渐变)。
为了创建一个线性渐变,你要调用CGGradientCreateWithColorComponents函数。这个函数的返回值是一个新的类型为CGGradientRef的渐变,这是一个句柄。一旦你不再使用该渐变,你必须调用CGGradientRelease过程,传入之前你从CGGradientCreareWithColorComopnets获取到的渐变的句柄来释放资源。
CGGradientCreateWithColorComponents需要四个参数:
这是一个色彩范围的容器,类型必须是CGColorSpaceRef。对于这个参数,我们可以传入CGColorSpaceCreateDeviceRGB函数的返回值,它将给我们一个RGB色彩空间。
这个数组必须包含CGFloat类型的红、绿、蓝和alpha值。
此参数控制该渐变从一种颜色过渡到另一种颜色的速度有多快。该数组中元素的数量必须和第四个参数的值相同。
这个参数指明了我们需要多少颜色和位置
使用CGContextDrawLinearGradient过程在图形上下文中绘制该线性渐变。这人过程需要五个参数:
Graphics context
指定绘制线性渐变的图形上下文。
Axial gradient
我们使用CGGradientCreatWithColorComponents函数创建的线性渐变对象的句柄。
Start point
图形上下文中一个CGPoint类型的点,表示渐变的起点。
End point
图形上下文中一个CGPoint类型的点,表示渐变的终点。
Gradient drawing options
当你的起点或终点不在图形上下文的边缘内时,指定该如何处理。你可以使用你的开始或结束颜钯来填充渐变以外的空间。此参数为下列值之一:
kCGGradientDrawsAfterEndLocation
kCGGradientDrawsBeforeStartLocation
0
平移图形上下文中的形状
使用CGAffineTransformMakeTranslation函数,返回一个CGAffineTransform类型的仿射变换。这个函数指定X和Y方向上以点为单位的平移量。
可以改变CTM的配置,随后强制所有绘制在图形上下文的形状转移到画布上的别一个地方,而不是直接将变换应用到矩形上。
缩放图形上下文中的形状
CGAffineTransformMakeScale函数
旋转图形上下文中的形状
CGAffineTransformMakeRotation函数和一个旋转的弧度来获取一个CGAffineTransform类型的旋转变换。想对整个上下文旋转指定的角度。可以使用CGContextRotateCTM过程。
提供的旋转值必须是弧度的,正值代表顺时针旋转,而负值代表逆时针旋转。
动画
UIKit中实现动画的起点是调用UIView类的类方法beginAnimations:context。实际上不会马上执行而是直到你调用UIView类的commintAnimations类方法。
beginAnimations:context:
开始一个动画块。调用这个类方法后,对视图任何属必的改变,都会在动画块提效之后形成动画。
setAnimationDuration:
以秒为单位设置动画的持续时间。
setAnimationDelegate:
设置一个对象来接收动画开始之前、动画期间或动画结束之后发生的各种事件的委托对象。设置一个委托对象不会立即开始发送动画委托消息。你必须对视图对象使用其他的setter方法来告诉UIKit你的委托对象中的哪个选择器(selector)要接收哪些委托消息。
setAnimationDidStopSelector:
设置动画完成时委托对象中应该被高用的方法。这个方法按照以下顺序接受三个参数:
1. NSString类型的动画标识:它包含在动画开始时传给beginAnimations:context:方法的动画标识
2. 一个“已完成”的标识,NSNumber类型:此参数包含一个由NSNumber包装的布尔装,如果动画在被其他代码停止之前能够完整地执行,运行时(Runtime)将它设置为YES。如果这个值被设置为NO,意味着动画在完成之前被中断了。
3. 一个void*类型的上下文:这是动画开始时传给beginAnimations:context:方法的上下文。beginAnimations:context:中。
setAnimationWillStrartSelector:
设置动画即将开始时委托对象中被调用选择器。传给这个方法的选择器按照以下顺序接受两个参数:
1. NSString类型的动画标识:运行时将它设置为动画开始时传给beginAnimations:context:方法的动画标识;
2. 一个void*类型的上下文:这是动画开始时传给beginAnimations:context:方法的上下文。beginAnimations:context:中。
setAnimationDelay:
设置一个动画启动的延迟时间(以秒为单位)。
setAnimationRepeatCount:
设置一个动画需要重复它的动画的次数。
如果缩放视图使用缩放变换可以使用视图的中心作为缩放中心。如果通过增加frame高和宽来缩放视图,最终视图会位于屏幕的其它位置。因为你也改变了frame的x和y值。