今天上午去了一家公司面试,面试的技术总监居然是老乡,呵呵不过面试的过程还是正规的,他没有”徇私情“,呵呵。我比较喜欢这类的公司,完全接受顾客的app定制需求,专攻技术解决满足需求,和我之前的公司只是让我来维护或者开发他们维护网站的客户端而已,希望能够加入他们。
我零零碎碎地学习这iOS的开发,为了应付各种公司的面试,现在都不知道要着重看哪个了,今天就挑自己喜欢的科目:动画吧。想想当初被iOS吸引不就是这些特效吗。
Core Animation又叫Quatz Core是一个Object-C类库,直接内建于iOS的媒体层之中,UIKit中有些API是可以访问Core Animation的许多层面,你可以使用UIView的一些属性就可以轻易地用动画的方式表现出来,这些属性有:
frame:视图的边框,定义了矩形的宽和高,以及视图在其父视图中的起点的位置;
bound:视图的边界,同样也定义宽和高,不过起点是相对于当前视图的,通常是(0,0);
center:定义了视图在其父视图的中心的位置;
transform:视图的变换,定义了其相对中心点的缩放、旋转或者坐标转换等。UIKit的api限制变换只能位于二维空间(三位变换必须用Core Animation来做);
alpha:视图的整体透明度;
backgroundColor:视图的背景颜色;
contentStretch:视图的拉伸模式,决定了其宗的内容是如何填充可用的空间的。例如,一个UIImageView中的图像,如果是缩放填充(scale-to-fill)模式的话,可以以动画方式转换成缩放适应(scale-to-fit)模式。
要想使用Core Animation首先得导入Quartz Core框架,再导入头文件<QuartzCore/QuartzCore.h>,先来个简单的改变UIView及其子类的属性的动画:
UIView *box = [[UIView alloc] initWithFrame:CGRectMake(10, 10, 50, 50)];
box.backgroundColor = [UIColor blueColor];
[self.view addSubview:box];
[UIView beginAnimations:@"box-animation" context:nil];
[UIView setAnimationDuration:5];
box.backgroundColor = [UIColor redColor];
box.frame = CGRectMake(50, 50, 10, 10);
box.alpha = .5;
[UIView commitAnimation];
[box release];
很简单就是把box的背景颜色从蓝色改成红色,大小位置也发生变换,不过和颜色改变是同时发生的。
之前也接触到代码块block的介绍,这里动画也能使用的上,将上面这个动画用代码块改写成这样:
[UIView animateWithDuration:1 delay:0 options:UIViewAnimationCurveLinear animations:^(void){
box.backgroundColor = [UIColor yellowColor];
box.frame = CGRectMake(50, 50, 100, 100);
box.alpha = 0.8;
}
completion:^(BOOL finished ){
NSLog(@"Animation Finished");
}];
[UIView commitAnimations];
[box release];
不过我自己改了改,也不完全一样,原理就是这样把要变化后的状态写到代码块中,倒是比上面精简了许多,我自己是这样认为的。
以上两种都是利用UIKit来实现动画,你会发现给你自由发挥的余地很小,Apple当然不会扼杀programer的创造力,你可以使用CALayer,layer是UIView的一个底层表现形式,给我的感觉就像Ps的层,但又不像那么回事,下面就将动画赋予layer上:
CABasicAnimation *animation = [CABasicAnimation animation];
animation.toValue = (id) [UIColor blueColor].CGColor;
animation.duration = 2;
animation.autoreverses = YES;
[self.view.layer addAnimation:animation forKey:@"backgroundColor"];
这段代码就是让我的启动页面的背景颜色变成蓝色再变回去,是一种显示动画。给layer添加动画的forKey参数比较重要,要对应用来进行动画的属性的名称一致,不过你要设置视图的特定属性,如宽度,可以使用点分割语法来引用一个结构内部的成员变量。举个栗子:[self.layer addAnimation:animatoon forKey:@"bounds.size.width"];
上述也不是个性化的动画,那么关键帧动画可就是完全有程序员自行设计了,绝对独一无二:
CAKeyframeAnimation *animation = [CAKeyframeAnimation animation];
animation.values = [NSArray arrayWithObjects:
(id)self.view.layer.backgroundColor,
(id)[UIColor yellowColor].CGColor,
(id)[UIColor greenColor].CGColor,
(id)[UIColor blueColor].CGColor, nil];
animation.duration = 3;
animation.autoreverses = YES;
[self.view.layer addAnimation:animation forKey:@"backgroundColor"];
这个是把每个关键帧装载到一个values里面,回依次执行到每一个关键帧,下面就是通过自己绘制路径点,也就是是那关键的地方,让我们的UIView子类动起来:
UIView *ball = [[UIView alloc] initWithFrame:CGRectMake(20, 20, 30, 30)];
ball.backgroundColor = [UIColor redColor];
[self.view addSubview:ball];
CAKeyframeAnimation *ani = [CAKeyframeAnimation animation];
CGMutablePathRef aPath = CGPathCreateMutable();
CGPathMoveToPoint(aPath, nil, 20, 20);
CGPathAddCurveToPoint(aPath, nil, 160, 30, 220, 220, 240, 380);
ani.path = aPath;
ani.duration = 1;
ani.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseIn];
ani.rotationMode = @"auto";
[ball.layer addAnimation:ani forKey:@"position"];
CFRelease(aPath);
这个我加工了一下,这个本是iphone自带邮件里的一个动画,我自己建立一个长和宽都为30像素的UIView代替邮件图标,增加了三个控制点(160,30)、(220,220)、(240,380),iOS会自动平滑地连接器这三个点为一条线,设置好动画的时间为1秒,计时函数使用渐快的那个参数EaseIn模拟重力效果,如何改变方向,将rotation设置为auto就可以了,自己找切线方向运动,最后别忘了清理内存。图层就会按照制定的路线运动了。