CALayer as SubLayer Not Visible
Asked Answered
F

2

5

I am trying to built an animated circle which would be drawn clockwise until it becomes complete circle as illustrated in iPhone Core Animation - Drawing a Circle

Problem is that CALayer object is not added or build. I tested and saw that it is not accessing my drawInContext:CGContextRef and animatingArc methods.

What so far I have done is:

In AnimateArc.h

@interface AnimateArc : CALayer {

CAShapeLayer *circle;
}

-(void) animatingArc;

@end

In AnimateArc.m

-(void) drawInContext:(CGContextRef)ctx
{
CGFloat radius = 50.0;
circle = [CAShapeLayer layer];

//make a circular shape
circle.path = [UIBezierPath bezierPathWithRoundedRect:CGRectMake(0.0, 0.0, 2 * radius, 2 * radius) cornerRadius:radius].CGPath;

    CGPoint centerPoint = CGPointMake(CGRectGetWidth(self.bounds)/2, CGRectGetHeight(self.bounds)/2);    

//center the shape in self.view
circle.position = centerPoint;

//configure appearence of circle
circle.fillColor = [UIColor clearColor].CGColor;
circle.strokeColor = [UIColor blackColor].CGColor;
circle.lineWidth = 5;                                           

/*CGPointMake((self.contentsCenter.size.width), (self.contentsCenter.size.height));*/

//path the circle
CGContextAddArc(ctx, centerPoint.x, centerPoint.y, radius, 0.0, 2 * M_PI, 0);
CGContextClosePath(ctx);

//fill it
CGContextSetFillColorWithColor(ctx, [UIColor redColor].CGColor);
CGContextFillPath(ctx); }

///////////////////////////////////////////////////////////////////////

-(void) animatingArc
{
CABasicAnimation *anim = [CABasicAnimation animationWithKeyPath:@"arcEnd"];
anim.duration = 20.0; //animate over 20 seconds
anim.repeatCount = 1.0; //animate only once
anim.removedOnCompletion = NO; //Reamin there after completion

//animate from start to end
anim.fromValue = [NSNumber numberWithFloat:50.0f];
anim.toValue = [NSNumber numberWithFloat:150.0f];

//experiment with timing to get appearence to look the way you want
anim.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseIn];

//add animation to circle
[circle addAnimation:anim forKey:@"animatingArc"]; 
}

/////////////////////

//needed since key not part of animatable properties
+(BOOL) needsDisplayForKey:(NSString *)key
{
if([key isEqualToString:@"arcEnd"])
    return YES;
else
    return [super needsDisplayForKey:key];

}

//ensure custom properties copied to presentation layer
-(id) initWithLayer:(id)layer
{
if((self = [super initWithLayer:layer]))
{
    if ([layer isKindOfClass:[AnimateArc class]])
    {
        AnimateArc *other = (AnimateArc *) layer;
        [other setNeedsDisplay];
    }
}
return self; }

And finally in my viewController,

- (void)viewDidLoad
{
[super viewDidLoad];
[self.view.layer addSublayer:AnimateArcObject];
[AnimateArcObject animatingArc];
 }

Apology for bad formatting.... Please can someone tell me what am I doing wrong? I have also doubt that my code can crash at any place after accessing those two functions since I am novice about Core Animation and haven't got any idea that I am in right direction or not.

Any help will be appreciated. Thanks.

Faucet answered 21/7, 2012 at 20:17 Comment(0)
F
0

After little searching, I thought that I am going in wrong direction. So I deleted this AnimateArc file and added new one which is inheriting from UIViewController.

Then in viewDidLoad Method, I wrote the code from this link to create circle and animations using path.

In parent view controller, I added AnimatedArc ViewController's subview. Now its working perfectly :)

Faucet answered 12/8, 2012 at 4:21 Comment(0)
A
21

From my painful experience with CoreAnimation, you must always set the bounds property of any CALayer you instantiate.

So, you're layer is not showing because you are missing something like:

layer.bounds = CGRectMake(0, 0, width, height);

you should place this as soon as you instantiate the layer, and make it a habit to do so, so you don't fall into it again.

As for your code crashing, sorry. It's too distributed and I am not sure how it's linked together, so I can't help you there.

Anticipate answered 21/7, 2012 at 22:29 Comment(4)
Thanks for your reply. But setting bounds still didn't solve my problem :(Faucet
It helped me, but didn't fully solve it. The layer is now drawing on screen, but slightly offset from the parent view/layer even when I set the layer's bounds to the parent views frame. I'm missing something fundamental it seems.Clive
@tracicot you must set the bounds of the layer to origin (0, 0). Then, use the center property to change the position. You can also set the layer frame directly to control the position.Anticipate
Thanks, @Mazyod. I've send the bounds as you said, and the frame to be the same frame as the parent view in order to control the layer's position, but still no luck.Clive
F
0

After little searching, I thought that I am going in wrong direction. So I deleted this AnimateArc file and added new one which is inheriting from UIViewController.

Then in viewDidLoad Method, I wrote the code from this link to create circle and animations using path.

In parent view controller, I added AnimatedArc ViewController's subview. Now its working perfectly :)

Faucet answered 12/8, 2012 at 4:21 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.