彩票走势图

Xamarin使用教程十二:iOS中的视图动画

转帖|使用教程|编辑:我只采一朵|2014-09-01 10:12:28.000|阅读 1719 次

概述:在 iOS 系统中,Core Animation提供了内置的动画支持,创建动画不需要任何绘图的代码,你要做的只是激发指定的动画, 接下来就交给 Core Animation 来渲染。总之,复杂的动画只需要几行代码就可以了。

# 慧都年终大促·界面/图表报表/文档/IDE等千款热门软控件火热促销中 >>

相关链接:

动画为用户界面的状态转换提供了流畅的可视化效果,在iOS中大量使用了动画效果, 包括改变视图位置、大小、从可视化树中删除视图,隐藏视图等。你可以考虑用动画效果给用户提供反馈或者用来实现有趣的特效。

在 iOS 系统中,Core Animation提供了内置的动画支持,创建动画不需要任何绘图的代码,你要做的只是激发指定的动画, 接下来就交给 Core Animation 来渲染。总之,复杂的动画只需要几行代码就可以了。

哪些属性可以添加动画效果

根据 中说明, UIView 内置支持为下列属性添加动画效果:

  • Frame 可以改变视图相对于上一级视图的位置和大小。 (如果视图已经经过了缩放、 旋转、平移之类的变换, 则需要修改 Center 和 Bounds 属性)
  • Bounds 改变视图大小。
  • Center 改变视图相对于上级视图的位置。
  • Transform 相对于中心点进行视图缩放、旋转和平移, 这个属性只能进行二维转换。 (如果要进行三维转换, 则必须用 CoreAnimation 操作视图的 Layer 属性。)
  • Alpha 改变视图的透明度。
  • BackgroundColor 修改视图的背景色。
  • ContentStretch 改变视图内容在视图的可用空间内的拉伸方式。

为视图的属性变化添加动画

为了给属性的变化添加动画效果, 需要把修改这些属性的代码放到指定的动画代码段 (animation block) 中。 只有在动画代码段中修改支持动画的属性, 才能添加动画效果。

使用 Begin/Commit 方法做动画

在 iOS 3.0 以及之前的系统中, 必须使用 UIView 的类方法 和 来定义动画代码段, 在 begin 和 commit 之间的代码会在特殊的动画线程中运行, 因此不会阻塞主线程, 比如说要切换两个视图, 代码应该是这样子的:

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

在 Xamarin.iOS (MonoTouch) 平台下, begin/end 方法对应的绑定为:

public static void BeginAnimations (string animation)
public static void BeginAnimations (string animationID, IntPtr context)
public static void CommitAnimations ()

上面的切换视图的 C# 版本代码为:

UIView.BeginAnimations("ToggleViews");
UIView.SetAnimationDuration(1.0)
this.FirstView.Alpha = 0.0;
this.SecondView.Alpha = 1.0;
UIView.CommitAnidations();

在 Begin/Commit 函数之间, 可以通过下面的方法设置动画的参数和选项:

    setAnimationStartDate:
    setAnimationDelay:
    setAnimationDuration:
    setAnimationCurve:
    setAnimationRepeatCount:
    setAnimationRepeatAutoreverses:
    setAnimationDelegate:
    setAnimationWillStartSelector:
    setAnimationDidStopSelector:
    setAnimationBeginsFromCurrentState:

注意: 如果不是为了支持很旧的设备,则推荐使用下面的 lambda (block based method) 来实现动画效果, 虽然 begin/commit 还能够使用, 按照官方的说法, 对新系统来说是不推荐的了。

使用 lambda (block based method) 做动画

在 iOS 4.0 以后, 引入了代码块 (code block) 的概念, 可以使用代码块来初始化动画, 这也是在 iOS 4.0 之后苹果推荐的做法, iOS SDK 提供的 API 如下:


    animateWithDuration:animations:
    animateWithDuration:animations:completion:
    animateWithDuration:delay:options:animations:completion:

而在 Xamarin.iOS (MonoTouch) 平台下, 这些方法被绑定为下列方法:


    public static void Animate(double duration, NSAction animation)
    public static void Animate (double duration, NSAction animation, NSAction completion)
    public static void Animate (double duration, double delay, UIViewAnimationOptions options, NSAction animation, NSAction completion)

还是切换视图的动画, 如果用 objective-c 的代码块来实现, 则应该是这样子的:

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

如果用 C# 来实现的话, 应该是这样:

UIView.Animate(1.0, () => {
    this.FirstView.Alpha = 0.0f;
    this.SecondView.Alpha = 1.0f;
});

这样就实现了一个简单的渐变动画, 并且只能运行一次, 通常不能满足需求, 再来一个复杂点儿的:

[UIView animateWithDuration:1.0
        delay:0.0
        options:UIViewAnimationOptionCurveEaseIn
        animations:^{
            self.firstView.alpha = 0.0;
        }
        completion:^(BOOL finished){
            [UIView animateWithDuration:1.0
                    delay:1.0
                    options:UIViewAnimationOptionCurveEaseOut animations:^{
                        self.firstView.alpha = 1.0;
                    }
                    completion:nil];
}];

对应的 C# 代码如下:

UIView.Animate(
    1.0,
    0.0,
    UIViewAnimationOptions.CurveEaseIn,
    () => this.FirstView.Alpha = 0.0f,
    () => {
        UIView.Animate(
            1.0,
            1.0,
            UIViewAnimationOptions.CurveEaseOut,
            () => this.FirstView.Alpha = 1.0f,
            null
        );
    }
);

嵌套动画

iOS 支持嵌套的动画, 也就是说在一个动画代码段中, 可以再开始另外一个动画代码段, 而不必等当前动画完成, 嵌套的动画会同时开始运行, 默认继承原来动画的延时、 时间长度、 加速曲线等, 不过这些选项也能被覆盖。 例如:

[UIView animateWithDuration:1.0
    delay:1.0
    options:UIViewAnimationOptionCurveEaseOut animations:^{
        self.firstView.alpha = 0.0f;
        // 这里开始一个新的动画
        [UIView animateWithDuration:1.0
            delay:0.0
            options:UIViewAnimationOptionOverrideInheritedCurve |
                UIViewAnimationOptionCurveLinear |
                UIViewAnimationOptionOverrideInheritedDuration |
                UIViewAnimationOptionRepeat |
                UIViewAnimationOptionAutoreverse
            animations:^{
                [UIView setAnimationRepeatCount:2.5];
                self.secondView.alpha = 0.0f;
            }
            completion:nil];
    }
    completion:nil
];

对应的 C# 代码如下:

UIView.Animate(
    1.0,
    1.0,
    UIViewAnimationOptions.CurveEaseIn,
    () => {
        this.FirstView.Alpha = 0.0;
        UIView.Animate(
            1.0,
            1.0,
            UIViewAnimationOptions.OverrideInheritedCurve |
            UIViewAnimationOptions.CurveLinear |
            UIViewAnimationOptions.OverrideInheritedDuration |
            UIViewAnimationOptions.Repeat |
            UIViewAnimationOptions.Autoreverse,
            () => {
                UIView.SetAnimationRepeatCount(2.f);
                this.SecondView.Alpha = 0.0;
            },
            null
        );
    },
    null
);

对于使用 Begin/Commit 方法的动画, 也可以嵌套调用 Begin/Commit 方法来实现嵌套的动画, 例如:

UIView.BeginAnimations("Animation1");
// Animation code goes here
    // Start another animation
    UIView.BeginAnimations("Nested animation");
    // nested animations code goes here.
    UIView.CommitAnimations();
// other code
UIView.CommitAnimations();

这段 C# 代码对应的 ObjC 代码很简单, 就不写出来了。

实现动画的自动翻转

当创建自动翻转指定次数的动画时, 考虑将重复次数设置为非整数值。 因为对于自动翻转的动画来说, 每次循环都是从原始值变化到目标值再变化回原始值, 如果希望动画结束之后停留在目标值, 需要将重复次数设置加上 0.5 , 否则, 动画回慢慢变回原始值, 再迅速变化到目标值, 这可能不是原来期望的动画效果。

创建视图切换动画

视图切换动画可以减少修改可视化树时引起的界面上的突变, iOS 系统中大量使用了视图切换动画, 视图切换动画主要有下面两种场景:

  • 修改子视图
  • 替换子视图

注意: 不要把视图切换和视图控制器的切换混淆(显示一个模式对话框、将视图控制器推入导航堆栈等), 视图切换改变的仅仅是视图的可视化树, 视图控制器是不变的, 更多信息可以参考。

修改子视图

可以修改子视图的可见性用来表示当前视图的不同的状态, 看下面的两个视图切换的例子,在 iOS 4.0 之前, 需要将视图切换动画添加到 Begin/Commit 动画之间, 代码如下:

在 iOS 4.0 之后, 可以使用

[UIView transitionWithView:self.view
    duration:1.0
    options:UIViewAnimationOptionTransitionCurlUp
    animations:^{
        self.currentView.hidden = YES;
        self.swapView.hidden = NO;
    }
    completion:^(BOOL finished) {
        UIView *tmp = self.currentView;
        self.currentView = self.swapView;
        self.swapView = tmp;
    }
];

在 iOS 4.0 之前需要用到的函数是 对应的代码如下:

[UIView beginAnimations:@"toggleView" context:nil];
[UIView setAnimationTransition:UIViewAnimationTransitionCurlUp forView:self.view cache:YES];
[UIView setAnimationDuration:1.0];
// animation goes here
self.currentView.hidden = YES;
self.swapView.hidden = NO;
[UIView commitAnimations];

这里只有动画部分的代码, 动画完成之后请参考 方法设置并实现 UIAnimationDelegate 。

替换子视图

要进行子视图的替换, 需要用到 方法, 示例代码如下:

UIView *fromView = (self.displayPrimary ? self.view : self.secondView);
UIView *toView = (self.displayPrimary ? self.secondView : self.view);
UIViewAnimationOptions option = (self.displayPrimary ? UIViewAnimationOptionTransitionFlipFromRight
                                : UIViewAnimationOptionTransitionFlipFromLeft);
[UIView transitionFromView:fromView toView:toView duration:1.0 options:option
    completion:^(BOOL finished) {
        if (finished) {
        self.displayPrimary = !self.displayPrimary;
        }
    }
];

链接多个动画

有了上面的知识, 链接多个动画就非常简单了:

  • 对于 lambda 或 block-based 方法的动画, 使用 complete 回调函数即可;
  • 对于 Begin/Commit 方法的动画, 需要实现一个 UIAnimationDelegate , 然后调用 setAnimationDelegate 方法设置 Delegate 即可。

标签:iOSXamarin

本站文章除注明转载外,均为本站原创或翻译。欢迎任何形式的转载,但请务必注明出处、不得修改原文相关链接,如果存在内容上的异议请邮件反馈至chenjj@pclwef.cn


为你推荐

  • 推荐视频
  • 推荐活动
  • 推荐产品
  • 推荐文章
  • 慧都慧问
扫码咨询


添加微信 立即咨询

电话咨询

客服热线
023-68661681

TOP