简体   繁体   中英

How do I convert a CGColor into an NSObject when using Monotouch?

I am trying to animate a CGColor fillColor property on a CAShapeLayer. I can get it working just fine using Objective-C with the following syntax:

- (void)viewDidLoad {
    [super viewDidLoad];

    // Create the path
    thisPath = CGPathCreateMutable();
    CGPathMoveToPoint(thisPath, NULL, 100.0f, 50.0f);
    CGPathAddLineToPoint(thisPath, NULL, 10.0f, 140.0f);
    CGPathAddLineToPoint(thisPath, NULL, 180.0f, 140.0f);
    CGPathCloseSubpath(thisPath);

    // Create shape layer
    shapeLayer = [CAShapeLayer layer];
    shapeLayer.frame = self.view.bounds;
    shapeLayer.path = thisPath;
    shapeLayer.fillColor = [UIColor redColor].CGColor;

    [self.view.layer addSublayer:shapeLayer];

    // Add the animation
    CABasicAnimation* colorAnimation = [CABasicAnimation animationWithKeyPath:@"fillColor"];
    colorAnimation.duration = 4.0;
    colorAnimation.repeatCount = 1e100f;
    colorAnimation.autoreverses = YES;
    colorAnimation.fromValue = (id) [UIColor redColor].CGColor;
    colorAnimation.toValue = (id) [UIColor blueColor].CGColor;
    [shapeLayer addAnimation:colorAnimation forKey:@"animateColor"];
}

This animates the color shift as expected. When I port this to Monotouch, I tried:

    public override void ViewDidLoad ()
    {
        base.ViewDidLoad ();

        thisPath = new CGPath();
        thisPath.MoveToPoint(100,50);
        thisPath.AddLineToPoint(10,140);
        thisPath.AddLineToPoint(180,140);
        thisPath.CloseSubpath();

        shapeLayer = new CAShapeLayer();
        shapeLayer.Path = thisPath;
        shapeLayer.FillColor = UIColor.Red.CGColor;

        View.Layer.AddSublayer(shapeLayer);

        CABasicAnimation colorAnimation = CABasicAnimation.FromKeyPath("fillColor");
        colorAnimation.Duration = 4;
        colorAnimation.RepeatCount = float.PositiveInfinity;
        colorAnimation.AutoReverses = true;
        colorAnimation.From = NSObject.FromObject(UIColor.Red.CGColor);
        colorAnimation.To = NSObject.FromObject(UIColor.Blue.CGColor);

        shapeLayer.AddAnimation(colorAnimation, "animateColor");
    }

but the animation never plays. The animationStarted event does get raised, so presumably it is trying to run the animation, but I don't see any visible evidence on the screen.

I've been playing with this for the better part of a day and I think it's the conversion from a CGColor into an NSObject - I've tried NSObject.FromObject, NSValue.ValueFromHandle, etc. but haven't found any way to get the animation to correctly pickup the start and end values.

What is the proper way to supply a CGColor as an NSObject for an animation?

Thanks!

Mark,

You can use

colorAnimation.To = Runtime.GetNSObject (UIColor.Blue.CGColor.Handle);

to get the right object for the animation.

Kudos to https://stackoverflow.com/users/187720/geoff-norton for actually giving me the answer to use Runtime.GetNSObject and to fix this issue.

Hope this helps,

ChrisNTR

It's also possible to do:

colorAnimation.From = NSObject.FromObject (UIColor.Red.CGColor.Handle);

and the next versions of MonoTouch (6.0.8+) will allow:

colorAnimation.From = NSObject.FromObject (UIColor.Red.CGColor);

and the same for CGPath and other INativeObject that are not NSObject .

I've just looked at some similar code written in our app (admittedly CAKeyFrameAnimation rather than CABasicAnimation ) and they seem to have wrapped the .AddAnimation() in a UIView animation block. Eg:

UIView.Animate(4, delegate{
    shapeLayer.AddAnimation(colorAnimation, "animateColor");
});

I'm not sure if this is the correct way of doing this, but it seems to work in our app.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM