Animations
可以动画显示的视图属性
1.UIKit和Core Animation都支持动画效果。在UIKit中,动画是通过UIView对象来实现,视图支持许多基本动画
2.视图的可动画改变的属性,frame, bounds, center, transform, alpha, backgroundColor, contentStretch
3.Core Animation用于更加复杂的动画效果
4.因为视图和其layer连接在一起,因此改变视图的layer也会影响到视图
5.Core Animation可以运用的地方:
-
改变layer的大小和位置
-
用于变换的中心点
-
Transformations to the layer or its sublayers in 3D space
-
The addition or removal of a layer from the layer hierarchy
-
The layer’s Z-order relative to other sibling layers
-
The layer’s shadow
-
The layer’s border (including whether the layer’s corners are rounded)
-
The portion of the layer that stretches during resizing operations
-
The layer’s opacity
-
The clipping behavior for sublayers that lie outside the layer’s bounds
-
The current contents of the layer
-
The rasterization behavior of the layer
6.Begin From Current State Option 如果设置此选项,那么如果在动画中改变了一些属性,那么动画会从当前状态开始新的动画。否则,动画会直接将属性设置为最终的值,然后再开始新的动画
用动画实现视图属性的改变
1.因为动画块不是和一个单独的视图连接起来,因此可以在同一个动画块中设置多个视图的动画
- <span style="font-size:16px;">[UIView animateWithDuration:1.0 animations:^{
- firstView.alpha = 0.0;
- secondView.alpha = 1.0;
- }];
- </span>
2.当指定动画开始的时候,动画会在另外一个线程上运行,以避免影响当前程序的主线程
3.使用completion handler
- - (IBAction)showHideView:(id)sender
- {
- // Fade out the view right away
- [UIView animateWithDuration:1.0
- delay: 0.0
- options: UIViewAnimationOptionCurveEaseIn
- animations:^{
- thirdView.alpha = 0.0;
- }
- completion:^(BOOL finished){
- // Wait one second and then fade in the view
- [UIView animateWithDuration:1.0
- delay: 1.0
- options:UIViewAnimationOptionCurveEaseOut
- animations:^{
- thirdView.alpha = 1.0;
- }
- completion:nil];
- }];
- }
4. 当你改变一个已经在动画改变的属性时,并不会停止当前动画。相反,当前的动画会继续,但是将你新指定的属性作为最终属性的结果来产生新动画
动画块的嵌入
1.嵌入的动画块与外部动画块同时开始,不过动画的配置可以不同。默认情况下,内部动画块继承外部动画块的时间,动画时间曲线。但是你也可以重新定义这些选项
- [UIView animateWithDuration:1.0
- delay: 1.0
- options:UIViewAnimationOptionCurveEaseOut
- animations:^{
- aView.alpha = 0.0;
-
- // Create a nested animation that has a different
- // duration, timing curve, and configuration.
- [UIView animateWithDuration:0.2
- delay:0.0
- <span style="color:#ff0000;"> options: UIViewAnimationOptionOverrideInheritedCurve |
- UIViewAnimationOptionCurveLinear |
- UIViewAnimationOptionOverrideInheritedDuration |
- UIViewAnimationOptionRepeat |
- UIViewAnimationOptionAutoreverse</span>
- animations:^{
- <span style="color:#ff0000;"> [UIView setAnimationRepeatCount:2.5];
- </span> anotherView.alpha = 0.0;
- }
- completion:nil];
-
- }
- completion:nil];
2. UIViewAnimationOptionOverrideInheritedCurve
andUIViewAnimationOptionOverrideInheritedDuration
两个键用于指定内部动画块需要重载的选项
3.注意设置动画重复次数的设置位置
4.对于可逆动画来说UIViewAnimationOptionAutoreverse,每一个循环包括了用动画将属性设置为新值(0.5)然后再将其设置为初始值(0.5)。如果你希望动画以属性的新值结束,则可以使用0.5次的重复次数。
创建视图的动画变换
1.对以下改变使用视图变换动画:
2.使用视图变换方法会对整个视图进行变换,但是变换之后只是视图的内容(子视图)发生了变换。视图变换与添加modal view类似,只不过当前的视图控制器不会发生改变。
4.在该动画块中,会动画改变的是子视图的添加,隐藏,显示,移除。
5.视图会创建改变之前和之后的视图的截图,然后动画切换他们
- - (IBAction)displayNewPage:(id)sender
- {
- [UIView transitionWithView:self.view
- duration:1.0
- options:UIViewAnimationOptionTransitionCurlUp
- animations:^{
- currentTextView.hidden = YES;
- swapTextView.hidden = NO;
- }
- completion:^(BOOL finished){
- // Save the old text and then swap the views.
- [self saveNotes:temp];
-
- UIView* temp = currentTextView;
- currentTextView = swapTextView;
- swapTextView = temp;
- }];
- }
- [UIView beginAnimations:@"ToggleSiblings" context:nil];
- [UIView setAnimationTransition:UIViewAnimationTransitionCurlUp forView:self.view cache:YES];
- [UIView setAnimationDuration:1.0];
-
- // Make your changes
-
- [UIView commitAnimations];
将一个视图替换为另外一个视图
2.如果要保留第一个视图,那么保存一个对其的引用
- - (IBAction)toggleMainViews:(id)sender {
- [UIView transitionFromView:(displayingPrimary ? primaryView : secondaryView)
- toView:(displayingPrimary ? secondaryView : primaryView)
- duration:1.0
- options:(displayingPrimary ? UIViewAnimationOptionTransitionFlipFromRight :
- UIViewAnimationOptionTransitionFlipFromLeft)
- completion:^(BOOL finished) {
- if (finished) {
- displayingPrimary = !displayingPrimary;
- }
- }];
- }
动画改变视图和layer
- [UIView animateWithDuration:1.0
- delay:0.0
- options: UIViewAnimationOptionCurveLinear
- animations:^{
- // Animate the first half of the view rotation.
- CGAffineTransform xform = CGAffineTransformMakeRotation(DEGREES_TO_RADIANS(-180));
- backingView.transform = xform;
-
- // Rotate the embedded CALayer in the opposite direction.
- CABasicAnimation* layerAnimation = [CABasicAnimation animationWithKeyPath:@"transform"];
- layerAnimation.duration = 2.0;
- layerAnimation.beginTime = 0; //CACurrentMediaTime() + 1;
- layerAnimation.valueFunction = [CAValueFunction functionWithName:kCAValueFunctionRotateZ];
- layerAnimation.timingFunction = [CAMediaTimingFunction
- functionWithName:kCAMediaTimingFunctionLinear];
- layerAnimation.fromValue = [NSNumber numberWithFloat:0.0];
- layerAnimation.toValue = [NSNumber numberWithFloat:DEGREES_TO_RADIANS(360.0)];
- layerAnimation.byValue = [NSNumber numberWithFloat:DEGREES_TO_RADIANS(180.0)];
- [manLayer addAnimation:layerAnimation forKey:@"layerAnimation"];
- }
- completion:^(BOOL finished){
- // Now do the second half of the view rotation.
- [UIView animateWithDuration:1.0
- delay: 0.0
- options: UIViewAnimationOptionCurveLinear
- animations:^{
- CGAffineTransform xform = CGAffineTransformMakeRotation(DEGREES_TO_RADIANS(-359));
- backingView.transform = xform;
- }
- completion:^(BOOL finished){
- backingView.transform = CGAffineTransformIdentity;
- }];
- }];
iOS4之后的版本应该使用block animation方法
指定动画的代理对象,两个代理方法的selector应该满足一下格式
- (void)animationDidStop:(NSString *)animationID finished:(NSNumber *)finished context:(void *)context
Animating Views with Blocks
enum {
UIViewAnimationOptionLayoutSubviews = 1 << 0,
UIViewAnimationOptionAllowUserInteraction = 1 << 1,
UIViewAnimationOptionBeginFromCurrentState = 1 << 2,
UIViewAnimationOptionRepeat = 1 << 3,
UIViewAnimationOptionAutoreverse = 1 << 4,
UIViewAnimationOptionOverrideInheritedDuration = 1 << 5,
UIViewAnimationOptionOverrideInheritedCurve = 1 << 6,
UIViewAnimationOptionAllowAnimatedContent = 1 << 7,
UIViewAnimationOptionShowHideTransitionViews = 1 << 8,
UIViewAnimationOptionCurveEaseInOut = 0 << 16,
UIViewAnimationOptionCurveEaseIn = 1 << 16,
UIViewAnimationOptionCurveEaseOut = 2 << 16,
UIViewAnimationOptionCurveLinear = 3 << 16,
UIViewAnimationOptionTransitionNone = 0 << 20,
UIViewAnimationOptionTransitionFlipFromLeft = 1 << 20,
UIViewAnimationOptionTransitionFlipFromRight = 2 << 20,
UIViewAnimationOptionTransitionCurlUp = 3 << 20,
UIViewAnimationOptionTransitionCurlDown = 4 << 20,
};
typedef NSUInteger UIViewAnimationOptions;
1.UIImageView的图片切换动画设置
- self.imageView.animationImages = [NSArray arrayWithObjects:
- [UIImage imageNamed:@"campFire01.gif"],
- [UIImage imageNamed:@"campFire02.gif"],
- [UIImage imageNamed:@"campFire03.gif"],
- [UIImage imageNamed:@"campFire04.gif"], nil];
- self.imageView.animationDuration = 1.75;
- self.imageView.animationRepeatCount = 0;
- [self.imageView startAnimating];
-
2.LocateMe中
- [UIView setAnimationDuration:0.6];
- startButton.alpha = 1.0;
- descriptionLabel.alpha = 1.0;
- tableView.alpha = 0.0;
- [self.navigationItem setLeftBarButtonItem:nil animated:YES];
- [UIView commitAnimations];
-
- [NSTimer scheduledTimerWithTimeInterval:0.1 target:self selector:@selector(onTimer) userInfo:nil repeats:YES];
-
- - (void)onTimer
- {
- UIImageView* flakeView = [[UIImageView alloc] initWithImage:self.flakeImage];
-
- // use the random() function to randomize up our flake attributes
- int startX = round(random() % 320);
- int endX = round(random() % 320);
- double scale = 1 / round(random() % 100) + 1.0;
- double speed = 1 / round(random() % 100) + 1.0;
-
- // set the flake start position
- flakeView.frame = CGRectMake(startX, -100.0, 25.0 * scale, 25.0 * scale);
- flakeView.alpha = 0.25;
-
- // put the flake in our main view
- [self.view addSubview:flakeView];
-
- [UIView beginAnimations:nil context:flakeView];
- // set up how fast the flake will fall
- [UIView setAnimationDuration:5 * speed];
-
- // set the postion where flake will move to
- flakeView.frame = CGRectMake(endX, 500.0, 25.0 * scale, 25.0 * scale);
-
- // set a stop callback so we can cleanup the flake when it reaches the
- // end of its animation
- [UIView setAnimationDidStopSelector:@selector(onAnimationComplete:finished:context:)];
- [UIView setAnimationDelegate:self];
- [UIView commitAnimations];
-
- }
- <span style="font-size:16px;">- (void)onAnimationComplete:(NSString *)animationID finished:(NSNumber *)finished context:(void *)context {
- UIImageView *flakeView = context;
- [flakeView removeFromSuperview];
- [flakeView release];
- }</span>
4.Picnic中动画链的应用
- - (void)moveToLeft:(NSString *)animationID finished:(NSNumber *)finished context:(void *)context {
-
- if (bugDead) return;
-
- [UIView animateWithDuration:1.0 delay:2.0 options:UIViewAnimationCurveEaseIn | UIViewAnimationOptionAllowUserInteraction animations:^(void) {
- self.bugImage.center = CGPointMake(75, 200);
- } completion:^(BOOL finished) {
- [self faceRight:nil finished:nil context:nil];
- }];
- }
-
- - (void)faceRight:(NSString *)animationID finished:(NSNumber *)finished context:(void *)context {
-
- if (bugDead) return;
-
- [UIView animateWithDuration:1.0 delay:0.0 options:UIViewAnimationCurveEaseInOut | UIViewAnimationOptionAllowUserInteraction animations:^(void) {
- self.bugImage.transform = CGAffineTransformMakeRotation(M_PI);
- } completion:^(BOOL finished) {
- [self moveToRight:nil finished:nil context:nil];
- }];
- }
-
- - (void)moveToRight:(NSString *)animationID finished:(NSNumber *)finished context:(void *)context {
-
- if (bugDead) return;
-
- [UIView animateWithDuration:1.0 delay:2.0 options:UIViewAnimationCurveEaseInOut | UIViewAnimationOptionAllowUserInteraction animations:^(void) {
- self.bugImage.center = CGPointMake(230, 250);
- } completion:^(BOOL finished) {
- [self faceLeft:nil finished:nil context:nil];
- }];
- }
-
- - (void)faceLeft:(NSString *)animationID finished:(NSNumber *)finished context:(void *)context {
-
- if (bugDead) return;
-
- [UIView animateWithDuration:1.0 delay:0.0 options:UIViewAnimationCurveEaseInOut | UIViewAnimationOptionAllowUserInteraction animations:^(void) {
- self.bugImage.transform = CGAffineTransformMakeRotation(0);
- } completion:^(BOOL finished) {
- [self moveToLeft:nil finished:nil context:nil];
- }];
- }
5. 自定义图像提取器
- - (void)loadView
- {
- [self loadImages];
- UIScrollView *scrollView = [[UIScrollView alloc] initWithFrame:[UIScreen mainScreen].bounds];
-
- int row = 0;
- int column = 0;
- for (int i = 0; i < self.thumbnails.count; i++) {
-
- UIImage *image = [self.thumbnails objectAtIndex:i];
- UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
- button.frame = CGRectMake(82 * column + 5, 69 * row + 5, 64, 64);
- [button setImage:image forState:UIControlStateNormal];
- [button addTarget:self action:@selector(buttonClicked:) forControlEvents:UIControlEventTouchUpInside];
- button.tag = i;
-
- [scrollView addSubview:button];
-
- if(column == 3){
- column = 0;
- row++;
- } else {
- column++;
- }
- }
-
- scrollView.contentSize = CGSizeMake(320, 69 * row + 5);
-
- self.view = scrollView;
- [scrollView release];
- }