1203 - iOS◍ 文档: View Programming Guide for iOS -- iOS的视图编程指南 第四章 Animations

官网链接:

https://developer.apple.com/library/archive/documentation/WindowsViews/Conceptual/ViewPG_iPhoneOS/AnimatingViews/AnimatingViews.html#//apple_ref/doc/uid/TP40009503-CH6-SW1

参考链接(别人翻译好的):

https://www.cnblogs.com/patientAndPersist/p/3180394.html

Animations -- 动画

Animations provide fluid visual transitions between different states of your user interface. In iOS, animations are used extensively to reposition views, change their size, remove them from view hierarchies, and hide them. You might use animations to convey feedback to the user or to implement interesting visual effects.

     --动画提供流畅的视觉过渡,用来表示用户界面的不同状态之间的转换。 在iOS里,动画被广泛用于重定位视图,改变它们的尺寸,把它们从视图层次结构中删除,以及隐藏它们。你可以用动画来给用户传递反馈或实现有趣的视觉效果。

In iOS, creating sophisticated animations does not require you to write any drawing code. All of the animation techniques described in this chapter use the built-in support provided by Core Animation. All you have to do is trigger the animation and let Core Animation handle the rendering of individual frames. This makes creating sophisticated animations very easy with only a few lines of code.

       --在iOS中,创建复杂的动画并不要求你编写任何绘制代码。 所有本章描述的动画技术都由内核动画(Core Animation)内置提供。 所有你要做的是促发动画并让内核动画处理单个帧的渲染。 这使得创建复杂动画很简单,只需要很少几行代码。

What Can Be Animated? -- 什么可以动画化

Both UIKit and Core Animation provide support for animations, but the level of support provided by each technology varies. In UIKit, animations are performed using UIView objects. Views support a basic set of animations that cover many common tasks. For example, you can animate changes to properties of views or use transition animations to replace one set of views with another.

      --UIKit和Core Animation都提供了对动画的支持,但是每种技术所支持的等级并不同。 在UIKit中,动画由UIView对象执行。 view只支持了动画的一个基本集合,它覆盖了一些通用任务。比如,你可以用动画地修改视图属性使用过渡动画来把一个视图集替换为另一个视图集。

Table 4-1 lists the animatable properties—the properties that have built-in animation support—of the UIView class. Being animatable does not mean animations happen automatically. Changing the value of these properties normally just updates the property (and the view) immediately without an animation. To animate such a change, you must change the property’s value from inside an animation block, which is described in Animating Property Changes in a View.

         --表格4-1 列出了UIView类中可动画的各种属性---已经内置动画支持的各种属性。能够动画化并不意味着动画会自动发生。 改变这些属性通常只是立即更新该属性(以及视图),而不会触发动画效果。 要想动画这样一个改变,你必须在一个”动画块内部“改变属性的值,这在后面的“Animating Property Changes in a View.” 里有详细描述。

Table 4-1  Animatable UIView properties

★可动画的UIView属性:

Property

Changes you can make   --你可以做的修改

frame
边框

Modify this property to change the view’s size and position relative to its superview’s coordinate system. (If the transform property does not contain the identity transform, modify the bounds or center properties instead.)

     --修改该属性来改变视图的尺寸和在它父视图坐标系统里的位置。(如果transform 属性没有包含恒等变换--identity transform--, 用修改bounds 或 center属性替代)

bounds

边界

Modify this property to change the view’s size.     --修改该属性来改变视图自身的尺寸

center

父中的中心点

Modify this property to change the view’s position relative to its superview’s coordinate system.

   --修改该属性来改变视图位于其父视图坐标系统中的位置

transform

 变换

Modify this property to scale, rotate, or translate the view relative to its center point. Transformations using this property are always performed in 2D space. (To perform 3D transformations, you must animate the view’s layer object using Core Animation.)

    --修改该属性来缩放,旋转,或 做 围绕它center point的变化。 使用该属性的变换永远执行在2D空间。(要想执行3D变换,你必须使用Core Animation来动画视图的层对象。) 

alpha

不透明度 

Modify this property to gradually change the transparency of the view.
    --修改该属性来逐渐改变视图的不透明度

backgroundColor

 背景色

Modify this property to change the view’s background color.
   --修改此属性以更改视图的背景色。

contentStretch

Modify this property to change the way the view’s contents are stretched to fill the available space.

      --修改该属性来改变视图拉伸的方式拉伸视图填充视图的可用空间。

Animated view transitions are a way for you to make changes to your view hierarchy beyond those offered by view controllers. Although you should use view controllers to manage succinct view hierarchies, there may be times when you want to replace all or part of a view hierarchy. In those situations, you can use view-based transitions to animate the addition and removal of your views.

        --动画视图变换是一种方法,让你对 不是由vc提供的 视图层次结构做改变。尽管你应该使用vc来管理简洁的视图层次结构, 但是有些时候当你想替换层次结构的所有或部分内容时就可以使用动画的视图变换。在那些情况下,你可以使用基于视图的各种变换来动画视图的添加和删除操作。

In places where you want to perform more sophisticated animations, or animations not supported by the UIView class, you can use Core Animation and the view’s underlying layer to create the animation. Because view and layer objects are intricately linked together, changes to a view’s layer affect the view itself. Using Core Animation, you can animate the following types of changes for your view’s layer:

     --当你想执行更复杂的动画或执行不被UIView类支持的各种动画时,你可以使用Core Animation以及view的图层(underlying layer)来创建动画。 因为视图和层对象是错综复杂地被连接到一起的,所以对一个视图层的改变也将影响视图本身。 使用Core Animation , 你的view的图层的以下改变可以被动画

  • The size and position of the layer
       --层的尺寸和位置

  • The center point used when performing transformations
        --执行各种变换时使用的中心点

  • Transformations to the layer or its sublayers in 3D space
        --在3D空间里对层或其子层所做的各种变换

  • The addition or removal of a layer from the layer hierarchy
         --在层层次结构中添加或删除一个层 

  • The layer’s Z-order relative to other sibling layers
         --层相对于其它兄弟姐妹层的Z 顺序

  • 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
       --层的栅格化行为

Note: If your view hosts custom layer objects—that is, layer objects without an associated view—you must use Core Animation to animate any changes to them.

     --注意: 如果你的视图承载了自定义layer对象---就是说,没有相关联view的layer对象---你必须使用Core Animation 来动画它们的任何改变。

Although this chapter addresses a few Core Animation behaviors, it does so in relation to initiating them from your view code. For more complete information about how to use Core Animation to animate layers, see Core Animation Programming Guide and Core Animation Cookbook.

      --尽管本章讲演了一些Core Animation 行为,但是它是通过在你的视图代码中初始化它们来实现的。关于如何使用Core Animaiton 来动画层的完整信息,请看 Core Animation Programming Guide 和  Core Animation Cookbook.

Animating Property Changes in a View         -- 动画化view的属性

In order to animate changes to a property of the UIView class, you must wrap those changes inside an animation block. The term animation block is used in the generic sense to refer to any code that designates animatable changes. In iOS 4 and later, you create an animation block using block objects. In earlier versions of iOS, you mark the beginning and end of an animation block using special class methods of the UIView class. Both techniques support the same configuration options and offer the same amount of control over the animation execution. However, the block-based methods are preferred whenever possible.

       --为了动画UIView 类中属性的各种改变,你必须在一个动画块里包装这些改变。 一般意义上来说,动画块是指任何可动画改变的代码块。在iOS4以及之后的版本中,你可以使用代码块对象来创建一个动画块。 在iOS的早期版本中,你使用UIView类的特定的类方法来标记一个动画块的起始与结束。两项技术都支持同样的配置选项,并提供动画执行相同数量的控制。然而,只要可能,基于块的方法是优选

The following sections focus on the code you need in order to animate changes to view properties. For information about how to create animated transitions between sets of views, see Creating Animated Transitions Between Views.

Starting Animations Using the Block-Based Methods     

                --   使用基于动画代码块的方法开启动画

In iOS 4 and later, you use the block-based class methods to initiate animations. There are several block-based methods that offer different levels of configuration for the animation block. These methods are:

     --在iOS4以及之后的版本中,你可以使用基于块的“类方法”初始化各种动画下面有一些基于块的方法,用来为动画块提供不同层次的配置:

Because these are class methods, the animation blocks you create with them are not tied to a single view. Thus, you can use these methods to create a single animation that involves changes to multiple views. For example, Listing 4-1 shows the code needed to fade in one view while fading out another over a one second time period. When this code executes, the specified animations are started immediately on another thread so as to avoid blocking the current thread or your application’s main thread.

       --因为这些都是类方法,所以你用它们创建出来的动画块不跟单个视图绑定。 因此,你可以使用这些方法来创建设计多个视图改变的单个动画。比如,列表4-1显示了一些代码,代码实现在一秒内从一个视图内淡出,再淡入另一个视图。当该代码被执行时,指定动画立即在其它线程里启动以免阻塞当前线程或应用程序的主线程。

Listing 4-1  Performing a simple block-based animation

   --列表 4-1 执行一个简单的基于块的动画:

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

}];

The animations in the preceding example run only once using an ease-in, ease-out animation curve. If you want to change the default animation parameters, you must use the animateWithDuration:delay:options:animations:completion: method to perform your animations. This method lets you customize the following animation parameters:

        --上例中的动画使用一个淡入,淡出动画曲线,它只被执行一次。如果你想要改变默认的动画参数,你必须使用animateWithDuration:delay:options:animations:completion: 方法来执行你的动画。该方法让你自定义以下动画参数:

  • The delay to use before starting the animation
       --启动动画前的延迟时间

  • The type of timing curve to use during the animation
      --在动画期间使用的时间曲线类型

  • The number of times the animation should repeat
       --动画重复的次数

  • Whether the animation should reverse itself automatically when it reaches the end
        --动画结束时是否自动反转(reverse)

  • Whether touch events are delivered to views while the animations are in progress
        --动画进行时是否把触摸时间传递给视图

  • Whether the animation should interrupt any in-progress animations or wait until those are complete before starting
        --动画是否应该中断任何正在进行的动画,或者等到这些都完成后才启动

Another thing that both the animateWithDuration:animations:completion: and animateWithDuration:delay:options:animations:completion: methods support is the ability to specify a completion handler block. You might use a completion handler to signal your application that a specific animation has finished. Completion handlers are also the way to link separate animations together.

      --animateWithDuration:animations:completion: 方法和animateWithDuration:delay:options:animations: completion: 方法都有设置一个动画结束后的“处理代码块”的能力。 你可以使用一个”结束代码块“来通知app一个特定动画已经结束。结束代码块也同样是连接分离动画的一种方法。

Listing 4-2 shows an example of an animation block that uses a completion handler to initiate a new animation after the first one finishes. The first call to animateWithDuration:delay:options:animations:completion: sets up a fade-out animation and configures it with some custom options. When that animation is complete, its completion handler runs and sets up the second half of the animation, which fades the view back in after a delay.

     --列表 4-2 显示了一个例子,该例子实现了一个使用了一个“结束的处理代码块”的动画块在第一个动画结束后初始化一个新动画。第一次调用animateWithDuration:delay:options:animations:completion:建立看一个淡出动画并配置了一个自定义选项。 当那个动画结束时,它的”结束处理程序“启动并建立了半个第二个动画,该动画在一定延迟之后把视图重新淡入。

Using a completion handler is the primary way that you link multiple animations.

使用一个 结束处理程序连接多个动画的主要方法。

Listing 4-2  Creating an animation block with custom options

    --列表 4-2 用自定义选项创建一个动画块

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

Important: Changing the value of a property while an animation involving that property is already in progress does not stop the current animation. Instead, the current animation continues and animates to the new value you just assigned to the property.

    重要提示:当动画涉及的属性已经在处理中时,改变该属性的值并不会停止当前动画。它会继续当前动画并动画到刚分配给属性的新值

Starting Animations Using the Begin/Commit Methods

         -- 使用Begin/Commit方法开启动画,最原始的方法,很好用,但是现在已经不是这样写了

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 以及之前版本,你必须使用UIView类的beginAnimations:context: 和 commitAnimations类方法来定义你的动画块。这些方法标记动画块的起始和结束。你通过这些方法实现的任何可动画属性都在你调用commitAnimations方法之后动画它们的新值。动画发生的执行过程在辅助线程里执行,以避免阻塞当前线程或应用程序的主线程。

Note: If you are writing an application for iOS 4 or later, you should use the block-based methods for animating your content instead. For information on how to use those methods, see Starting Animations Using the Block-Based Methods.

 

Listing 4-3 shows the code needed to implement the same behavior as Listing 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.

Listing 4-3  Performing a simple begin/commit animation

    [UIView beginAnimations:@"ToggleViews" context:nil];

    [UIView setAnimationDuration:1.0];
    // Make the animatable changes.
    firstView.alpha = 0.0;
    secondView.alpha = 1.0; 
    // Commit the changes and perform the animation.
    [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 call setAnimationsEnabled: again to reenable animations. You can determine if animations are current enabled by calling the areAnimationsEnabled class method.

Note: Changing the value of a property while an animation involving that property is in progress does not stop the current animation. Instead, the animation continues and animates to the new value you just assigned to the property.

Configuring the Parameters for Begin/Commit Animations

To configure the animation parameters for a begin/commit animation block, you use any of several UIView class 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.

Table 4-2  Methods for configuring animation blocks

Method

Usage

setAnimationStartDate:

setAnimationDelay:

Use either of these methods to specify when the executions should begin executing. If the specified start date is in the past (or the delay is 0), the animations begin as soon as possible.

setAnimationDuration:

Use this method to set the period of time over which to execute the animations.

setAnimationCurve:

Use this method to set the timing curve of the animations. This controls whether animations execute linearly or change speed at certain times.

setAnimationRepeatCount:

setAnimationRepeatAutoreverses:

Use these methods to set the number of times the animation repeats and whether the animation runs in reverse at the end of each complete cycle. For more information about using these methods, see Implementing Animations That Reverse Themselves.

setAnimationDelegate:

setAnimationWillStartSelector:

setAnimationDidStopSelector:

Use these methods to execute code immediately before or after the animations. For more information about using a delegate, see Configuring an Animation Delegate.

setAnimationBeginsFromCurrentState:

Use this method to stop all previous animations immediately and start the new animations from the stopping point. If you pass NO to this method, instead of YES, the new animations do not begin executing until the previous animations stop.

Listing 4-4 shows the code needed to implement the same behavior as the code in Listing 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.

Listing 4-4  Configuring animation parameters using the begin/commit methods

// This method begins the first animation.

- (IBAction)showHideView:(id)sender

{
    [UIView beginAnimations:@"ShowHideView" context:nil];
    [UIView setAnimationCurve:UIViewAnimationCurveEaseIn];
    [UIView setAnimationDuration:1.0];
    [UIView setAnimationDelegate:self];
    [UIView setAnimationDidStopSelector:@selector(showHideDidStop:finished:context:)];
    // Make the animatable changes.
    thirdView.alpha = 0.0;

    // Commit the changes and perform the animation.
    [UIView commitAnimations];
}

// Called at the end of the preceding animation.
- (void)showHideDidStop:(NSString *)animationID finished:(NSNumber *)finished context:(void *)context

{

    [UIView beginAnimations:@"ShowHideView2" context:nil];
    [UIView setAnimationCurve:UIViewAnimationCurveEaseOut];
    [UIView setAnimationDuration:1.0];
    [UIView setAnimationDelay:1.0];
    thirdView.alpha = 1.0;
    [UIView commitAnimations];
}

Configuring an Animation Delegate

If you want to execute code immediately before or after an animation, you must associate a delegate object and a start or stop selector with your begin/commit animation block. You set your delegate object using the setAnimationDelegate: class method of UIView 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.

     --如果你想要在一个动画之前或之后立即执行代码,你必须关联一个委托对象以及一个带有begin/commit动画块的启动或停止selector。你使用UIView类的setAnimationDelegate: 来设置你的委托对象, 使用setAnimationWillStartSelector:  和 setAnimationDidStopSelector: 类方法来设置你的启动和停止selectors。 在动画期间,动画系统在适当的时候调用你的委托方法来执行你的代码。

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.

Note: Although animation delegates can be used in the block-based methods, there is generally no need to use them there. Instead, place any code you want to run before the animations at the beginning of your block and place any code you want to run after the animations finish in a completion handler.

 

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

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

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 to beginAnimations: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, adding 0.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之间的动画过渡

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.

Important: View transitions should not be confused with transitions initiated by view controllers, such as the presentation of modal view controllers or the pushing of new view controllers onto a navigation stack. View transitions affect the view hierarchy only, whereas view-controller transitions change the active view controller as well. Thus, for view transitions, the view controller that was active when you initiated the transition remains active when the transition finishes.

For more information about how you can use view controllers to present new content, see View Controller Programming Guide for iOS.

 

Changing the Subviews of a View                               -- 改变view中的子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 the transitionWithView: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.

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

If you need to perform view transitions in iOS 3.2 and earlier, you can use the setAnimationTransition: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 the transitionWithView: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 in Listing 4-6, you would need to configure an animation delegate with a did-stop handler as described in Configuring an Animation Delegate.

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

Replacing a View with a Different View                   -- 使用其他view取代当前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 the displayingPrimary 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  Toggling between two views in a view controller

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

Note: In addition to swapping out views, your view controller code needs to manage the loading and unloading of both the primary and secondary views. For information on how views are loaded and unloaded by a view controller, see View Controller Programming Guide for iOS.

 

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:

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             -- 动画化view和layer两者的变化

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 a CABasicAnimation object or some other concrete subclass of CAAnimation. 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 custom CALayer 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.

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

Note: In Listing 4-9, you could also create and apply the CABasicAnimation object outside of the view-based animation block to achieve the same results. All of the animations ultimately rely on Core Animation for their execution. Thus, if they are submitted at approximately the same time, they run together.

 

If precise timing between your view and layer based animations is required, it is recommended that you create all of the animations using Core Animation. You may find that some animations are easier to perform using Core Animation anyway. For example, the view-based rotation in Listing 4-9 requires a multistep sequence for rotations of more than 180 degrees, whereas the Core Animation portion uses a rotation value function that rotates from start to finish through a middle value.

For more information about how to create and configure animations using Core Animation, see Core Animation Programming Guide and Core Animation Cookbook.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值