# animation - 4

284人阅读 评论(0)

Starting Animations Using the Begin/Commit Methods

if your application runs in iOS 3.2 and earlier, you must use the beginAnimations:context:  and commitAnimations  class methods of UIView to define your animation blocks. These methods mark the beginning and end of your animation block. Any animatable properties you change between these methods are animated to their new values after you call the commitAnimations method. Execution of the animations occurs on a secondary thread so as to avoid blocking the current thread or your application’s main thread.

Listing 4-3 shows the code needed to implement the same behavior asListing 4-1 but using the begin/commit methods. As in Listing 4-1, this code fades one view out while fading another in over one second of time. However, in this example, you must set the duration of the animation using a separate method call.

    [UIView beginAnimations:@"ToggleViews" context:nil];
[UIView setAnimationDuration:1.0];  //分开地设置duration time.

firstView.alpha = 0.0;

[UIView commitAnimations];

By default, all animatable property changes within an animation block are animated. If you want to animate some changes but not others, use the setAnimationsEnabled: method to disable animations temporarily, make any changes that you do not want animated, and then callsetAnimationsEnabled: again to reenable animations. You can determine if animations are current enabled by calling the areAnimationsEnabled class method.

Configuring the Parameters for Begin/Commit Animations

To configure the animation parameters for a begin/commit animation block, you use any of severalUIViewclass methods. Table 4-2 lists these methods and describes how you use them to configure your animations. Most of these methods should be called only from inside a begin/commit animation block but some may also be used with block-based animations. If you do not call one of these methods from your animation block, a default value for the corresponding attribute is used. For more information about the default value associated with each method, see the method description in UIView Class Reference.

Listing 4-4 shows the code needed to implement the same behavior as the code inListing 4-2 but using the begin/commit methods. As before, this code fades out a view, waits one second, and then fades it back in. In order to implement the second part of the animation, the code sets up an animation delegate and implements a did-stop handler method. That handler method then sets up the second half of the animations and runs them.

4-4清单演示了与清单4-2相同的效果但是是使用begin/commit方法。和之前一样，代码从视图中移除，等待一秒钟，重新渐入视图。为了实现第二段的动画效果，代码设置了一个动画代理同时实现了 did-stop（“确实停止了”）的处理方法。这个处理方法设置了第二部分的动画操作同时执行他们。

    UIButton* button = [UIButton buttonWithType:UIButtonTypeCustom];
[button setFrame:CGRectMake(100, 200, 80, 80)];
[button setBackgroundColor:[UIColor blueColor]];
[button setTitle:@"点击我" forState:UIControlStateNormal];
forControlEvents:UIControlEventTouchUpInside];

self.firstView = [UIView new];
[self.firstView setFrame:CGRectMake(0, 0, 100, 100)];
[self.firstView setBackgroundColor:[UIColor greenColor]];


- (void)buttonClicked:(id)sender
{

[UIView beginAnimations:@"ShowHideView" context:nil];  //这里context:nil，值得思考
[UIView setAnimationCurve:UIViewAnimationCurveEaseIn];
[UIView setAnimationDuration:1.0];
[UIView setAnimationDelegate:self];
[UIView setAnimationDidStopSelector:@selector(showHideDidStop:finished:context:)];

self.firstView.alpha = 0.0;

[UIView commitAnimations];
}

- (void)showHideDidStop:(NSString*)animtaionID finished:(NSNumber*)finished context:(void*)context
{
[UIView beginAnimations:@"ShowHideView2" context:nil];
[UIView setAnimationCurve:UIViewAnimationCurveEaseOut];
[UIView setAnimationDuration:1.0];
[UIView setAnimationDelay:1.0];

self.firstView.alpha = 1.0;

[UIView commitAnimations];
}

+ (void)beginAnimations:(NSString *)animationID context:(void *)context;  // additional context info passed to will start/did stop selectors. begin/commit can be nested
context参数的类型是 void* ， 很炫酷吧，那么为什么要置nil，都需要思考一下。

Configuring an Animation Delegate

If you want to execute code immediately before or after an animation, you must associate adelegate object and a start or stop selector with your begin/commit animation block. You set your delegate object using the setAnimationDelegate:  class method ofUIView and you set your start and stop selectors using the setAnimationWillStartSelector: and setAnimationDidStopSelector: class methods. During the animation, the animation system calls your delegate methods at the appropriate times to give you a chance to perform your code.

The signatures of your animation delegate methods need to be similar to the following:

- (void)animationWillStart:(NSString *)animationID context:(void *)context;
- (void)animationDidStop:(NSString *)animationID finished:(NSNumber *)finished context:(void *)context;

The animationID and context parameters for both methods are the same parameters that you passed to the beginAnimations:context: method at the beginning of the animation block:

• animationID—An application-supplied string used to identify the animation.
• context—An application-supplied object that you can use to pass additional information to the delegate.

The setAnimationDidStopSelector: selector method has an additional parameter—a Boolean value that is YES if the animation ran to completion. If the value of this parameter is NO, the animation was either canceled or stopped prematurely by another animation.

• animationID — 应用程序提供的字符串用来定义动画  （就是动画名字呗）
• context — 一个应用程序提供的对象用来传递额外的信息给delegate的参数
setAnimationDidStopSelector:selector 方法拥有另外一个参数 — 一个布尔值如果是YES的话动画操作则将会完成。如果参数是NO，这个操作会被取消或者是是提早被其他动画停止。

Nesting Animation Blocks

You can assign different timing and configuration options to parts of an animation block by nesting additional animation blocks. As the name implies, a nested animation block is a new animation block created inside an existing animation block. Nested animations are started at the same time as any parent animations but run (for the most part) with their own configuration options. By default, nested animations do inherit the parent’s duration and animation curve but even those options can be overridden as needed.

Listing 4-5 shows an example of how a nested animation is used to change the timing, duration, and behavior of some animations in the overall group. In this case, two views are being faded to total transparency, but the transparency of the another View object is changed back and forth several times before it is finally hidden. The UIViewAnimationOptionOverrideInheritedCurve and UIViewAnimationOptionOverrideInheritedDuration keys used in the nested animation block allow the curve and duration values from the first animation to be modified for the second animation. If these keys were not present, the duration and curve of the outer animation block would be used instead.

UIViewAnimationOptionOverrideInheritedCurve UIViewAnimationOptionOverrideInheritedDuration关键字被用在嵌套的animation block允许这个运动曲线和持久时间的值从第一次动画到第二次动画的的修改变化而不同。如果这些关键字都没有被使用上，持久时间和运动曲线在外层的animation block将会替代。

    [UIView animateWithDuration:1.0
delay:1.0
options:UIViewAnimationOptionCurveEaseOut
animations:^{

self.firstView.alpha = 0.0;

[UIView animateWithDuration:0.2
delay:0.0
options:UIViewAnimationOptionOverrideInheritedCurve | UIViewAnimationOptionCurveLinear |UIViewAnimationOptionOverrideInheritedDuration | UIViewAnimationOptionRepeat | UIViewAnimationOptionAutoreverse
animations:^{

[UIView setAnimationRepeatCount:2.5];
secondView.alpha = 0.0;

}
completion:nil];

}
completion:nil];

If you are using the begin/commit methods to create your animations, nesting works in much the same way as with the block-based methods. Each successive call tobeginAnimations:context: within an already open animation block creates a new nested animation block that you can configure as needed. Any configuration changes you make apply to the most recently opened animation block. All animation blocks must be closed with a call to commitAnimations before the animations are submitted and executed.

Implementing Animations That Reverse Themselves

When creating reversible animations in conjunction with a repeat count, consider specifying a non integer value for the repeat count. For an autoreversing animation, each complete cycle of the animation involves animating from the original value to the new value and back again. If you want your animation to end on the new value, adding0.5 to the repeat count causes the animation to complete the extra half cycle needed to end at the new value. If you do not include this half step, your animation will animate to the original value and then snap quickly to the new value, which may not be the visual effect you want.

Creating Animated Transitions Between Views

View transitions help you hide sudden changes associated with adding, removing, hiding, or showing views in your view hierarchy. You use view transitions to implement the following types of changes:

• Change the visible subviews of an existing view. You typically choose this option when you want to make relatively small changes to an existing view.
• Replace one view in your view hierarchy with a different view. You typically choose this option when you want to replace a view hierarchy that spans all or most of the screen.
View Transitions 帮助你们来隐藏一些突然增加，移除，隐藏或者显示视图在你的视图继承层结构上。你使用视图转换来实现下面几种改变：

• 改变一些已经存在的可视的子视图. 你经常选择这一项当你想要给一些存在的视图做出一些相对的变化。
• 在你的视图继承层中用不同的视图来替换一些已经存在的视图. 你经常选择这一项当你想要给一些跨越整个或者大部分屏幕的视图层

Changing the Subviews of a View

Changing the subviews of a view allows you to make moderate changes to the view. For example, you might add or remove subviews to toggle the superview between two different states. By the time the animations finish, the same view is displayed but its contents are now different.

In iOS 4 and later, you use thetransitionWithView:duration:options:animations:completion:  method to initiate a transition animation for a view. In the animations block passed to this method, the only changes that are normally animated are those associated with showing, hiding, adding, or removing subviews. Limiting animations to this set allows the view to create a snapshot image of the before and after versions of the view and animate between the two images, which is more efficient. However, if you need to animate other changes, you can include the UIViewAnimationOptionAllowAnimatedContent  option when calling the method. Including that option prevents the view from creating snapshots and animates all changes directly.

Listing 4-6 is an example of how to use a transition animation to make it seem as if a new text entry page has been added. In this example, the main view contains two embedded text views. The text views are configured identically, but one is always visible while the other is always hidden. When the user taps the button to create a new page, this method toggles the visibility of the two views, resulting in a new empty page with an empty text view ready to accept text. After the transition is complete, the view saves the text from the old page using a private method and resets the now hidden text view so that it can be reused later. The view then arranges its pointers so that it can be ready to do the same thing if the user requests yet another new page.

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

If you need to perform view transitions in iOS 3.2 and earlier, you can use thesetAnimationTransition:forView:cache: method to specify the parameters for the transition. The view you pass to that method is the same one you would pass in as the first parameter to thetransitionWithView:duration:options:animations:completion: method. Listing 4-7 shows the basic structure of the animation block you need to create. Note that to implement the completion block shown inListing 4-6, you would need to

    [UIView beginAnimations:@"ToggleSiblings" context:nil];
[UIView setAnimationTransition:UIViewAnimationTransitionCurlUp forView:self.view cache:YES];
[UIView setAnimationDuration:1.0];

[UIView commitAnimations];

Replacing a View with a Different View

Replacing views is something you do when you want your interface to be dramatically different. Because this technique swaps only views (and not view controllers), you are responsible for designing your application’s controller objects appropriately. This technique is simply a way of presenting new views quickly using some standard transitions.

In iOS 4 and later, you use the transitionFromView:toView:duration:options:completion: method to transition between two views. This method actually removes the first view from your hierarchy and inserts the other, so you should make sure you have a reference to the first view if you want to keep it. If you want to hide views instead of remove them from your view hierarchy, pass the  UIViewAnimationOptionShowHideTransitionViews key as one of the options.

Listing 4-8 shows the code needed to swap between two main views managed by a single view controller. In this example, the view controller’s root view always displays one of two child views (primaryView or secondaryView). Each view presents the same content but does so in a different way. The view controller uses thedisplayingPrimary member variable (a Boolean value) to keep track of which view is displayed at any given time. The flip direction changes depending on which view is being displayed.

Listing 4-8 shows the code needed to swap between two main views managed by a single view controller. In this example, the view controller’s root view always displays one of two child views (primaryView or secondaryView). Each view presents the same content but does so in a different way. The view controller uses thedisplayingPrimary member variable (a Boolean value) to keep track of which view is displayed at any given time. The flip direction changes depending on which view is being displayed.

    [UIView transitionFromView:(displayPrimary ? self.labelOne : self.labelTwo)
toView:(displayPrimary ? self.labelTwo : self.labelOne)
duration:1.0
options:(displayPrimary ? UIViewAnimationOptionTransitionFlipFromRight : UIViewAnimationOptionTransitionFlipFromLeft)
completion:^(BOOL finished){

if (finished)
{
displayPrimary = !displayPrimary;
}
}];

The UIView animation interfaces provide support for linking separate animation blocks so that they perform sequentially instead of at the same time. The process for linking animation blocks depends on whether you are using the block-based animation methods or the begin/commit methods:

• For block-based animations, use the completion handler supported by the animateWithDuration:animations:completion:  and  animateWithDuration:delay:options:animations:completion: methods to execute any follow-on animations.
• For begin/commit animations, associate a delegate object and a did-stop selector with the animation. For information about how to associate a delegate with your animations, seeConfiguring an Animation Delegate.

An alternative to linking animations together is to use nested animations with different delay factors so as to start the animations at different times. For more information on how to nest animations, see Nesting Animation Blocks.

Animating View and Layer Changes Together

Applications can freely mix view-based and layer-based animation code as needed but the process for configuring your animation parameters depends on who owns the layer. Changing a view-owned layer is the same as changing the view itself, and any animations you apply to the layer’s properties respect the animation parameters of the current view-based animation block. The same is not true for layers that you create yourself. Custom layer objects ignore view-based animation block parameters and use the default Core Animation parameters instead.

If you want to customize the animation parameters for layers you create, you must use Core Animation directly. Typically, animating layers using Core Animation involves creating aCABasicAnimation object or some other concrete subclass ofCAAnimation. You then add that animation to the corresponding layer. You can apply the animation from either inside or outside a view-based animation block.

Listing 4-9 shows an animation that modifies a view and a custom layer at the same time. The view in this example contains a customCALayer object at the center of its bounds. The animation rotates the view counter clockwise while rotating the layer clockwise. Because the rotations are in opposite directions, the layer maintains its original orientation relative to the screen and does not appear to rotate significantly. However, the view beneath that layer spins 360 degrees and returns to its original orientation. This example is presented primarily to demonstrate how you can mix view and layer animations. This type of mixing should not be used in situations where precise timing is needed.

[UIView animateWithDuration:1.0
delay:0.0
options: UIViewAnimationOptionCurveLinear
animations:^{
// Animate the first half of the view rotation.
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];
}
completion:^(BOOL finished){
// Now do the second half of the view rotation.
[UIView animateWithDuration:1.0
delay: 0.0
options: UIViewAnimationOptionCurveLinear
animations:^{
backingView.transform = xform;
}
completion:^(BOOL finished){
backingView.transform = CGAffineTransformIdentity;
}];
}];

0
0

* 以上用户言论只代表其个人观点，不代表CSDN网站的观点或立场
个人资料
• 访问：79663次
• 积分：4416
• 等级：
• 排名：第7152名
• 原创：374篇
• 转载：7篇
• 译文：4篇
• 评论：4条
评论排行
最新评论