UIImageView提供了形式很简单的动画,可能这些不值得一提,尽管如此,有时候它就是你所须要的所有。你给UIImageView 的 animationImages 或者 highlightedAnimationImages属性 一个装有UIImage 的NSArray值,这个数组表明一个简单的动画片“帧”。但你发送 startAnimating消息,图片依次显示,帧率由animationDuration属性决定,重复次数由animationRepeatCount属性决定(默认是0,意味着无限重复,或者直到收到 stopAnimating 消息)。在动画以前和以后,这个UIImageView继续显示它的图片(或者 highlightedImage)。数组
例如,假设咱们但愿一张火星图片从某个地方冒出来,并在屏幕上闪烁三次。这彷佛须要某种以NSTimer为基础的解决方案,但使用UIImageView的动画就很是简单:动画
UIImage* mars = [UIImage imageNamed: @"Mars"]; UIGraphicsBeginImageContextWithOptions(mars.size, NO, 0); UIImage* empty = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext(); NSArray* arr = @[mars, empty, mars, empty, mars]; UIImageView* iv = [[UIImageView alloc] initWithImage:empty]; CGRect r = iv.frame; r.origin = CGPointMake(100,100); iv.frame = r; [self.view addSubview: iv]; iv.animationImages = arr; iv.animationDuration = 2; iv.animationRepeatCount = 1; [iv startAnimating];
您能够将UIImageView的动画与其余类型的动画结合起来。例如,您能够一边闪烁火星图像,而在同一时间向右滑动UIImageView,使用视图的动画将在后面看法。ui
此外,UIImage的动画提供了并行的形式:图像自己能够是一个动画对象。就像使用的UIImageView,这真的意味着你已经造成一个多张图片的序列做为一个简单的动画片“帧”。您可使用两个UIImage的类方法之一来指定一个图像做为动画对象:code
animatedImageWithImages:duration:orm
如同UIImageView的的动画图片,你提供UIImages的数组。还为整个动画提供了动画的持续时间。对象
animatedImageNamed:duration:图片
您提供的单个图像文件的名称,就像imageNamed:,不带文件扩展名。运行时会为您提供的名称后面追加@“0”(或者,若是失败了,@“1”),使该图像文件为动画序列的第一个图像。而后它递增所附加的数字,获取相应的图像,并将它们添加到序列中(直到没有更多图片,或者咱们达到@“1024”)。ip
还有一个第三方的方法:animatedResizableImageNamed:capInsets:resizing- Mode:duration:, 把可调整大小的图片和动画图像结合起来。animation
你并不能告诉一个动画形象开始执行动画,也不能告诉它你想要动画重复多久。相反,只要它出如今你的界面上,动画图像就始终在执行动画,每隔1秒的时间重复这个图片序列;为了控制动画,你能够从你的界面中添加或者删除这个图像,这样可能会让动画图像转变为一个没有动画的图像。此外,动画图像能够出如今任何一个UIImage会出现的一些界面对象的属性界面上。it
在这个例子中,我在代码中构建了不一样大小的红色圆圈序列,并创建一个动画形象,而后我在一个UIButton显示:
NSMutableArray* arr = [NSMutableArray array]; float w = 18; for (int i = 0; i < 6; i++) { UIGraphicsBeginImageContextWithOptions(CGSizeMake(w,w), NO, 0); CGContextRef con = UIGraphicsGetCurrentContext(); CGContextSetFillColorWithColor(con, [UIColor redColor].CGColor); CGContextAddEllipseInRect(con, CGRectMake(0+i,0+i,w-i*2,w-i*2)); CGContextFillPath(con); UIImage* im = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext(); [arr addObject:im]; } UIImage* im = [UIImage animatedImageWithImages:arr duration:0.5]; // assume b is a button in the interface [b setImage:im forState:UIControlStateNormal];
动画是最终层的动画。可是,在有限的属性范围内,你能够直接让UIView执行动画: 这些是它的 alpha, backgroundColor, bonds, center, frame 和 transform。 你也可让UIView内容的变化执行动画。这个名单尽管很简单,可是一般已经足够了。(若是执行不了动画,你能够用更加底层的技术,直接驱动 layer 来执行动画,后面会见到。)
使用UIView类方法来使一个UIView执行动画的语法,咱们通常使在block中描述咱们想要的动画。例如,假设咱们在界面上有一个背景颜色为黄色的UIView self.v ,咱们想要经过动画来改变该视图的背景颜色为红色。下面能够作到这一点:
[UIView animateWithDuration:0.4 animations:^{ self.v.backgroundColor = [UIColor redColor]; }];
在block中所作的变化都会执行动画,因此咱们能够经过动画来同时改变视图的位置和颜色:
[UIView animateWithDuration:0.4 animations:^{ self.v.backgroundColor = [UIColor redColor]; CGPoint p = self.v.center; p.y -= 100; self.v.center = p; }];
可是,有时在block中的某些操做咱们不想让它执行动画,在 iOS 7 中,咱们可使用 performWithoutAnimation: 方法来解决这个问题。下面的代码,视图会跳到它的新位置,而后背景颜色慢慢地变为红色:
[UIView animateWithDuration:0.4 animations:^{ self.v.backgroundColor = [UIColor redColor]; [UIView performWithoutAnimation:^{ CGPoint p = self.v.center; p.y -= 100; self.v.center = p; }]; }];
在block 中的代码会要求执行动画(不是performWithoutAnimation: block 中) -- 也就是,block中的代码给出了在重绘时刻执行什么样的动画。若是你把改变更画视图的某个属性做为动画的一部分,那么你在以后就不该该再改变它,不然结果会让人很困惑。例如,猜猜下面的代码会怎样:
[UIView animateWithDuration:2 animations:^{ CGPoint p = self.v.center; p.y = 100; self.v.center = p; CGPoint p2 = self.v.center; p2.y = 300; self.v.center = p2; }];
结果并非两个连续的动画。咱们在这里仅仅是一个动画包含相互矛盾的命令: 经过动画让视图的center 的 y 值变成 100、 经过动画让视图的center 的 y 值变成300。 第二个动画命令会致使第一个动画被取消。 因此,但执行动画时,视图会跳到 center 的 y 值 为100的位置,而后才以动画的形式下移200。
即便在block 以后改变这个值也会形成迷惑。猜猜下面的代码会怎样:
[UIView animateWithDuration:2 animations:^{ CGPoint p = self.v.center; p.y = 100; self.v.center = p; }]; CGPoint p2 = self.v.center; p2.y = 300; self.v.center = p2;
这个动画从它所在的位置开始,移动到center 的 y值为300的地方! 在block里面的代码根本没有执行。 跟在block后面的代码至关于在block中执行,它已经成为动画的一部分了,实际的效果跟下面的代码同样:
[UIView animateWithDuration:2 animations:^{ CGPoint p2 = self.v.center; p2.y = 300; self.v.center = p2; }];