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
[UIView animateWithDuration:1.0 animations:^{
firstView.alpha = 0.0;
secondView.alpha = 1.0;
}];
2.当指定动画开始的时候,动画会在另外一个线程上运行,以避免影响当前程序的主线程
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];
}];
}
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
两个键用于指定内部动画块需要重载的选项
-
Change the visible subviews of an existing view.
-
Replace one view in your view hierarchy with a different view.
Change the visible subviews of an existing view.
Replace one view in your view hierarchy with a different view.
transitionWithView:duration:options:animations:completion:
方法来初始化一个视图变换
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];
将一个视图替换为另外一个视图
transitionFromView:toView:duration:options:completion:
方法来切换视图,这个方法会将第一个视图从视图层次中删去,并插入第二个视图。
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;
}
}];
}
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:
-
+ setAnimationDuration:
-
+ setAnimationDelay:
-
+ setAnimationCurve:
-
typedef enum { UIViewAnimationCurveEaseInOut, UIViewAnimationCurveEaseIn, UIViewAnimationCurveEaseOut, UIViewAnimationCurveLinear } UIViewAnimationCurve;
-
+ setAnimationRepeatCount:
-
+ setAnimationRepeatAutoreverses:
-
+ setAnimationBeginsFromCurrentState:
-
+ setAnimationTransition:forView:cache:
-
+ areAnimationsEnabled
Animating Views with Blocks
-
+ animateWithDuration:delay:options:animations:completion:
-
+ animateWithDuration:animations:completion:
-
+ animateWithDuration:animations:
-
+ transitionWithView:duration:options:animations:completion:
-
+ transitionFromView:toView:duration:options:completion:
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]; }