animation - 4

来源:互联网 发布:微信企业号 php源码 编辑:程序博客网 时间:2024/05/16 13:03

接上animation - 3,继续从官方文档入手:

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.

如果你的应用在ios3.2或者之前,你必须调用方法 beginAnimations:context:   commitAnimations类方法来定义你的动画执行blocks。这些方法标志了你的animation block的开始和结束操作。任何可以动画操作的属性当你做修改的时候会动画演示它们的新值在你调用了commitAnimations方法后。对动画操作的执行会发生在第二线程为了避免阻塞当前的线程或者是你的主线程。


所以啊,多看官方文档咧,你看看beginAnimations:context 上下文执行动画这种方法多旧。。。

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.

列表4-3显示出与列表4-1同样的效果但是使用的是begin/commit方法。例如列表4-1中,这段代码在一个视图中渐入渐出在一秒钟以内。然而,在这个例子中,你必须用分开的方来设置动画的持久时间。

    [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.

默认地,所有的可动画操作的属性当伴随着animation block而变化是动画的。如果你想要用动画来展示一些改变而不是其它,使用:setAnimationsEnabled:方法来使得动画操作暂时无效,使得一些你不想它执行动画操作的变化没有执行,之后再调用setAnimationsEnabled:方法来使得动画无法执行。你可以确定是否动画操作能否在当前有效通过方法:areAnimationsEnabled的类方法。



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.

配置begin/commit animation block的相关的参数,你使用一些UIView的类方法。表4-2列出了这些方法并且描述出如何使用它们来配置你的动画操作。大多数的这些方法应该被调用仅仅从begin/commit animation block但是一些则需要用到block-based(基于block)的动画。如果你并没有从中调用方法,一些相关属性的默认值将会被用上。


这将会开一个专题来 - animation block。

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];    [button addTarget:self action:@selector(buttonClicked:)     forControlEvents:UIControlEventTouchUpInside];    [self.view addSubview:button];        self.firstView = [UIView new];    [self.firstView setFrame:CGRectMake(0, 0, 100, 100)];    [self.firstView setBackgroundColor:[UIColor greenColor]];    [self.view addSubview:self.firstView];

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

所以说有必要刷一贴关于API的文章,不管是animtion block还是begin/commit操作,因为很多知道怎么用,但是深层次的缺乏思考,例如:

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

如果你想要执行一段代码在动画执行之前或者之后,你必须用一个delegate对象来作联系并且开始或者停止一个方法用begin/commit animation block。你用setAnimationDelegate:方法来设置你的委托对象并且你设置你的开始和停止方法用setAnimationWillStartSelector: 和 setAnimationDidStopSelector:  的类方法。在动画期间,这个动画系统调用你的委托方法在适当的时期来给你时机去执行你的代码。

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 参数和你传递给 beginAnimations:context方法一样:

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


注意:尽管动画delegates可以被用到block-based方法,通常没有必要去使用它们。取而代之的是,放置一些你想去执行的代码在动画之前在你的block操作开始之前并且放置任意的代码块你想要执行在动画完成之后的回调操作里面。(block 轻便, 灵活 的完美体现啊!)


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.

你可以分配不同的计时和配置选项来作为一个animation block的部分通过嵌套额外的animation blocks。就如名字所暗示的,一个嵌套的animation block是一个新的animation block 在一个已经存在的animation block中被创建的。嵌套的动画操作会在同时执行并且作为parent animations“父动画操作”(对于大多数)而且是用它们自己的配置选项。默认地,嵌套的动画操作继承“父 动画操作”的持久时间和 animation curve(动画轨迹)即使它们的选项已经被重载了需要的时候。

清单4-5显示了一个例子如何让一个嵌套的动画操作被用在改变计时,持久时间和一些在整体组中的动画表现。在这种情况中,两个视图将会渐变成透明,但是另外一个视图对象又变回来几次在它彻底变的隐藏之前。

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 tocommitAnimations before the animations are submitted and executed.

如果你使用begin/commit 方法来创建你的动画操作,嵌套工作在大致和 block-based 方法的相同方式。每一个成功的对于 beginAnimations:context 方法的调用在一个已经打开的animation block创建了一个新的嵌套 animation block 并且你可以按照需要配置它们。(这句话很绕口,其实意思就是如上代码所示,你在已经进行的animation block中定义一个新的animation block : 其意思就是说open animaiton block)任意的配置改变了你最近应用上的打开后的animation block。所有的animation blocks都必须调用在封闭 commitAnimations 方法在动画提交并执行之前。

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.

当创建一个可转变的动画操作并且设置定了几个重复次数,考虑设定一个非整形多值给重复次数。对于一个自动转化动画操作,每一个完成的动画操作循环都包含了原始值到一个新创值并来回。如果你想你的动画以一个新值结束,给重复次数增加0.5将会导致这个动画完成这额外半个的循环并且达到一个新值。如果你并没有包含这个新的步骤,你的动画将会达到原始值并且很快地捕捉成新值,这可能不是你想要的效果。


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 帮助你们来隐藏一些突然增加,移除,隐藏或者显示视图在你的视图继承层结构上。你使用视图转换来实现下面几种改变:

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

这里提醒了,view transitions 和 纯粹的viewcontroller ( navigationController )的区别,一个只在当前的视图继承层上有操作,一个在navigationController Stack 栈上有操作。


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 theUIViewAnimationOptionAllowAnimatedContent  option when calling the method. Including that option prevents the view from creating snapshots and animates all changes directly.

改变视图的子视图让你能够给视图做出适度的修改。例如,你可能增加或者删除一些子类来触发父视图在两个不同的状态之间。在动画操作结束的同时,相同的视图将会展现出来但是它的内容将会不一样。

在iOS4或者以后的版本,你使用 transitionWithView:duration:options:animations:completion:  方法来初始化一个视图的转换动画。在这个传递给这个方法的 animations block ,这唯一的改变就是正常的动画操作一些联系如:显示,隐藏,增加或者移除子视图。让动画受限于此使得视图能够产生一个在之前的快照和之后的版本并且在这两个图像之间转换,这显得更有效。然而,如果你想要动画操作其它改变,你可以包含选项:UIViewAnimationOptionAllowAnimatedContent  当调用这个方法。则表明了这个选项阻止视图产生快照而直接演示所有的动画改变操作。

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.

清单4-6是一个例子演示了如何使用transition animation来使得看起来就像一个新的文本被添加进了页面的效果。在这个例子中,这个主视图包含了两个嵌入的文本视图。这两个文本视图配置相同,但是一个总是可见的而另外一个总是隐藏的。当用户点击一个按钮来产生一个新的页面,这个方法出发了这两个视图的可视化,导致一个有空白文本视图的新的空页面预备接受文本。在这些转换完成之后,这个视图从旧的页面保存了这些文本使用一个私有方法并且重置了现在隐藏的文本视图以至于能够在后面被使用。这个视图在之后准备了它的指针以至于它能够准备做相同的事情如果这个用户要求另外一个新的页面。

- (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;        }];}
苹果的这份文档也是奇怪, [self saveNotes: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

在iOS3.2之前你要是想使用view transitions,你可以使用setAnimationTransition:forView:cache:方法来指定这些转换需要的参数。view是相同于上面的那个方法。清单4-7显示了你需要创建的基础的animation block的结构。注意到上面清单4-6所实现的completion block:

    [UIView beginAnimations:@"ToggleSiblings" context:nil];    [UIView setAnimationTransition:UIViewAnimationTransitionCurlUp forView:self.view cache:YES];    [UIView setAnimationDuration:1.0];     // Make your changes     [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;                        }                    }];

这个也是很炫的效果。

Linking Multiple Animations Together

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.

可以连接多重动画,就是连续的动画,一个就是用animation block,一个就是使用动画委托: aniamtion delegates。



这个可是重点啊!

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.

应用程序可以自由地搭配基于视图的和基于层的(view-based and layer-based)动画代码在需要的时候但是这个去配置你的动画参数的过程取决于谁拥有这个层(注意这里的用词,owns the layer, layer 作为属性被拥有)。改变一个拥有视图的层的效果和改变这个视图本身一样,并且任何你提供给这个层属性的动画都遵循当前view-based的animation block的动画参数。The same is not true for layers that you create yourself.(不会翻译。。)自定义的层对象会忽视view-based animation block参数并且使用默认的Core Animation 参数作为替代。

如果你想要自定义动画参数给你所创建的layers,你直接地必须使用Core Animation(一言道出UIView animation 和 Core Animation 之间的关系啦。)通常来说,设计动画的层使用了Core Animation 涉及到了创建了 CABasicAnimaiton 对象或者 其它具体的CAAniamtion的子类。然后你把这些动画添加在相关的layer当中。你在内部或者在外部可以提供一个view-based animation block来作为操作。

清单4-9演示了一个同时修改了一个视图和一个自定义层的动画例子。这个在例子当中的视图包含了一个自定义CALayer对象在它的界面的中间。这个动画操作顺时针地旋转这个视图但是旋转这个层逆时针。因为旋转的方向是相反的,层保持其原来的方向相对于屏幕所以没有显著的旋转。但是,这个在层之前的视图旋转了360度并且回到它原来的方向。这个例子主要是来阐述你如何能够混合view和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;         }];}];

这段代码关于CALayer的处理真的不是很会,有待在Core Animation里面的学习。


终于将UIView相关的文档简单刷了一遍,接下来就是对优秀的博客的学习了。







0 0
原创粉丝点击