如何使用Monotouch同时将动画应用于两个图层

时间:2011-09-09 06:16:28

标签: c# animation xamarin.ios

我正在尝试使用Monotouch动画在屏幕上移动的两个图像。我一直在研究CATransaction和Animation组,但MonoTouch示例很少且公平,这两个对象似乎只适用于一层。

是否有人能够指出使用什么类型的对象同时为两个图像制作动画的正确方向?

由于

        MovePos(img);
        MovePos(img2);

        public void MovePos (UIView view)
        {
            var theAnimation = CABasicAnimation.FromKeyPath ("position");
            theAnimation.Duration = 2;
            theAnimation.From = NSValue.FromPointF (new PointF (74, 74));
            theAnimation.To = NSValue.FromPointF (new PointF (566, 406));
            theAnimation.TimingFunction = new CAMediaTimingFunction (0.25f ,0.1f ,0.25f ,1.0f);

            view.Layer.AddAnimation (theAnimation, "animateLabel"); 
        }

2 个答案:

答案 0 :(得分:3)

您可以查看TweetStation的“滑动”单元格支持的源代码,该支持会立即执行varios动画:

  • 它将单元格设置为右侧
  • 它在图标
  • 中消失
  • 它使图标增长,然后缩小到它们的大小
  • 退回上一个现有菜单

所有这些都是在一次交易中完成的。源代码位于:

https://github.com/migueldeicaza/TweetStation/blob/06e2ae5484103a85660201592bd7f06fb1b69395/TweetStation/UI/SwipeSupport.cs

动画实际上分布在不同的地方。 SwipeMenuView在其构造函数上配置自己的动画(将图标淡入背景,增长/缩小图标),并将动画添加到CAAnimationGroup,并使用layer.AddAnimation(group)将生成的动画添加到图层:

此方法的代码段位于:

    var alpha = (CAKeyFrameAnimation) CAKeyFrameAnimation.FromKeyPath ("opacity");
    alpha.Values = new NSNumber [] {
        NSNumber.FromFloat (0),
        NSNumber.FromFloat (0.1f),
        NSNumber.FromFloat (1),
    };
    alpha.KeyTimes = new NSNumber [] {
        NSNumber.FromFloat (0),
        NSNumber.FromFloat (1f/(layers.Length-i)),
        NSNumber.FromFloat (1),
    };

    var size = (CAKeyFrameAnimation) CAKeyFrameAnimation.FromKeyPath ("transform.scale");
    size.Values = new NSNumber [] {
        NSNumber.FromFloat (0.7f),
        NSNumber.FromFloat (1.3f),
        NSNumber.FromFloat (1),
    };

    var group = CAAnimationGroup.CreateAnimation ();
    group.Animations = new CAAnimation [] { alpha, size /*, pos */ };
    group.Duration = delay; 

    layer.AddAnimation (group, "showup");                   

动画的另一部分是在ShowMenu中配置的,一个人从屏幕上滑动单元格,如果已经显示了一个菜单,它会将单元格设置为动画,然后将其反弹回新位置:

ShowMenu通过对UIView.BeginAnimations()和UIView.CommitAnimations分隔的事务块中的更改进行分组来触发动画:

        UIView.BeginAnimations ("Foo");
        UIView.SetAnimationDuration (hideDelay);
        UIView.SetAnimationCurve (UIViewAnimationCurve.EaseInOut);          

        var animation = MakeBounceAnimation (Math.Abs (offset), "position.x");

        foreach (var view in menuCell.ContentView.Subviews){
            if (view == currentMenuView)
                continue;

            view.SetNeedsDisplay ();
            AnimateBack (view, animation);
        }
        AnimateBack (menuCell.SelectedBackgroundView, animation);

        UIView.CommitAnimations ();

创建菜单动画以产生弹跳效果:

CAAnimation MakeBounceAnimation (float offset, string key)
{
    var animation = (CAKeyFrameAnimation) CAKeyFrameAnimation.FromKeyPath (key);

    animation.Duration = hideDelay;
    float left = offset/2;
    animation.Values = new NSNumber [] {
        NSNumber.FromFloat (offset+left),
        NSNumber.FromFloat (left-30),
        NSNumber.FromFloat (left+10),
        NSNumber.FromFloat (left-10),
        NSNumber.FromFloat (left),
    };

    return animation;
}

AnimateBack方法仅附加动画:

void AnimateBack (UIView view, CAAnimation animation)
{
    var b = view.Bounds;
    view.Layer.Position = new PointF (b.Width/2, b.Height/2);
    view.Layer.AddAnimation (animation, "position");
}

答案 1 :(得分:0)

我使用三种不同的方法来动画对象。根据您的需要,这个应该在你的控制范围内工作:

Animate (animationDuration, 0, UIViewAnimationOptions.CurveEaseOut, delegate {
    //your changes here
    Position = new PointF (566, 406);
    }, null);

如果这没有帮助,您可以改用:

BeginAnimations("MovingStuff");
SetAnimationDuration(2f);
//your changes here, you can modify multiple objects at once and then commit it all together.
Position = new PointF (566, 406);
CommitAnimations();