开发者

How to apply animation to two layers simultaneously using Monotouch

开发者 https://www.devze.com 2023-04-03 13:12 出处:网络
I\'m trying to animate two images moving across the screen using Monotouch. I\'ve been looking into CATransaction and Animation group, but MonoTouch examples are few and fair between, and both these o

I'm trying to animate two images moving across the screen using Monotouch. I've been looking into CATransaction and Animation group, but MonoTouch examples are few and fair between, and both these objects seem to apply to only one layer.

Would someone be able to point in the right direction on what sort of object to use to animate both images at the same time?

Thanks

        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"); 
        开发者_如何学Python}


You can look at the source code for TweetStation's "swipe" cell support, which performs varios animations at once:

  • It animates the cell to the right
  • It fades in the icons
  • It makes the icon grow and then scale back to their size
  • Bounces the previous existing menu

All of those are done in a single transaction. The source code is in:

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

The animations are actually spread across various places. The SwipeMenuView configures its own animation (fading the icons into the background, growing/shrinking the icons) on its constructor and the animation is added to a CAAnimationGroup and the resulting animation is added to the layer, by using layer.AddAnimation (group):

A code snippet of this method is here:

    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");                   

The other part of the animation is configured in ShowMenu, that one swipes the cell out of the screen and if there was already a menu displayed, it animates the cell back bouncing it back to its new location:

ShowMenu triggers the animations by grouping the changes in a transaction block delimited by UIView.BeginAnimations () and 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 ();

The menu animation is created to have a bouncing effect:

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

The AnimateBack method merely attaches the animation:

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");
}


I use three different ways to animate an object. For your needs this one should work inside your control:

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

If this does not help, you can use this instead:

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();
0

精彩评论

暂无评论...
验证码 换一张
取 消