UIView Animation的一些用法

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.因为动画块不是和一个单独的视图连接起来,因此可以在同一个动画块中设置多个视图的动画

[UIView animateWithDuration:1.0 animations:^{
        firstView.alpha = 0.0;
        secondView.alpha = 1.0;
}];

2.当指定动画开始的时候,动画会在另外一个线程上运行,以避免影响当前程序的主线程
3.使用completion handler
Listing 4-2  Creating an animation block with custom options
- (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.嵌入的动画块与外部动画块同时开始,不过动画的配置可以不同。默认情况下,内部动画块继承外部动画块的时间,动画时间曲线。但是你也可以重新定义这些选项

Listing 4-5  Nesting animations that have different configurations
[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
                 options: UIViewAnimationOptionOverrideInheritedCurve |
                          UIViewAnimationOptionCurveLinear |
                          UIViewAnimationOptionOverrideInheritedDuration |
                          UIViewAnimationOptionRepeat |
                          UIViewAnimationOptionAutoreverse
                 animations:^{
                      [UIView setAnimationRepeatCount:2.5];
                      anotherView.alpha = 0.0;
                 }
                 completion:nil];
 
        }
        completion:nil];
2. UIViewAnimationOptionOverrideInheritedCurve andUIViewAnimationOptionOverrideInheritedDuration 两个键用于指定内部动画块需要重载的选项 
3.注意设置动画重复次数的设置位置
4.对于可逆动画来说UIViewAnimationOptionAutoreverse,每一个循环包括了用动画将属性设置为新值(0.5)然后再将其设置为初始值(0.5)。如果你希望动画以属性的新值结束,则可以使用0.5次的重复次数。


创建视图的动画变换

1.对以下改变使用视图变换动画:
  • Change the visible subviews of an existing view. 

  • Replace one view in your view hierarchy with a different view.

2.使用视图变换方法会对整个视图进行变换,但是变换之后只是视图的内容(子视图)发生了变换。视图变换与添加modal view类似,只不过当前的视图控制器不会发生改变。
3.使用 transitionWithView:duration:options:animations:completion: 方法来初始化一个视图变换
4.在该动画块中,会动画改变的是子视图的添加,隐藏,显示,移除。
5.视图会创建改变之前和之后的视图的截图,然后动画切换他们

Listing 4-6  Swapping an empty text view for an existing one
- (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;
        }];
}

Listing 4-7  Changing subviews using the begin/commit methods
    [UIView beginAnimations:@"ToggleSiblings" context:nil];
    [UIView setAnimationTransition:UIViewAnimationTransitionCurlUp forView:self.view cache:YES];
    [UIView setAnimationDuration:1.0];
 
    // Make your changes
 
    [UIView commitAnimations];

将一个视图替换为另外一个视图

1.使用 transitionFromView:toView:duration:options:completion: 方法来切换视图,这个方法会将第一个视图从视图层次中删去,并插入第二个视图。
2.如果要保留第一个视图,那么保存一个对其的引用
3.如果你只是想要隐藏而不是从视图层次中移除视图,那么使用UIViewAnimationOptionShowHideTransitionViews 

- (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

Listing 4-9  Mixing view and layer animations
[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方法

  • + (void)beginAnimations:(NSString *)animationID context:(void *)context
    标记动画的开始,第一参数指定动画的ID,第二个参数表示要传递的自定义数据
  • + commitAnimations
  • + setAnimationStartDate:
  • + setAnimationsEnabled:

  • + setAnimationDelegate:
  • + setAnimationWillStartSelector:
  • + setAnimationDidStopSelector:
指定动画的代理对象,两个代理方法的selector应该满足一下格式
- (void)animationDidStop:(NSString *)animationID finished:(NSNumber *)finished context:(void *)context

  • + setAnimationDuration:
  • + setAnimationDelay:
  • + setAnimationCurve:
  • typedef enum {
       UIViewAnimationCurveEaseInOut,
       UIViewAnimationCurveEaseIn,
       UIViewAnimationCurveEaseOut,
       UIViewAnimationCurveLinear
    } UIViewAnimationCurve;
    

  • + setAnimationRepeatCount:
  • + setAnimationRepeatAutoreverses:
  • + setAnimationBeginsFromCurrentState:
  • + setAnimationTransition:forView:cache:
  • + areAnimationsEnabled


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 beginAnimations:@"Reset" context:nil];
    [UIView setAnimationDuration:0.6];
    startButton.alpha = 1.0;
    descriptionLabel.alpha = 1.0;
    tableView.alpha = 0.0;
    [self.navigationItem setLeftBarButtonItem:nil animated:YES];
    [UIView commitAnimations];



3.SnowFall

	[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];
	
}

- (void)onAnimationComplete:(NSString *)animationID finished:(NSNumber *)finished context:(void *)context {
	UIImageView *flakeView = context;
	[flakeView removeFromSuperview];
	[flakeView release];
}


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];
}









  • 0
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值