CoreAnimation CALayer and CATextLayer combination

2019-04-09 02:47发布

I'am just playing around with CA lately. Now I am kind of stuck. This is the thing I want to animate: enter image description here

As for now I already got the circle animation working. I subclassed CALayer to make the animation. I really don't know where to go from here. Where do I have to add the sublayer of CATextLayer? How do I animate both at the same time so it looks like the text with its line is sticking at the circle end?

If you need some code or anything else let me know.

I would be really happy to get some help here :-)

Thanks a lot!

2条回答
一纸荒年 Trace。
2楼-- · 2019-04-09 03:30

I was able to do what you are asking for below. Code is very rough, just spent a couple minutes on it, may have missed releases and what have you. You can simply swap the UILabel for a CATextLayer (used UILabel for brevity).

    CAShapeLayer* circle = [[CAShapeLayer alloc] init];
    CGMutablePathRef path = CGPathCreateMutable();
    CGRect textRect = CGRectMake(self.bounds.size.width/4, (self.bounds.size.height-self.bounds.size.width/2)/2, self.bounds.size.width/2, self.bounds.size.width/2);
    float midX = CGRectGetMidX(textRect);
    float midY = CGRectGetMidY(textRect);
    CGAffineTransform t = CGAffineTransformConcat(
                            CGAffineTransformConcat(
                                CGAffineTransformMakeTranslation(-midX, -midY), 
                                CGAffineTransformMakeRotation(-1.57079633/0.99)), 
                            CGAffineTransformMakeTranslation(midX, midY));
    CGPathAddEllipseInRect(path, &t, textRect);
    circle.path = path;
    circle.frame = self.bounds;
    circle.fillColor = [UIColor clearColor].CGColor;
    circle.strokeColor = [UIColor blackColor].CGColor;
    circle.lineWidth = 60.0f;
    [self.layer addSublayer:circle];

    CABasicAnimation* animation = [CABasicAnimation animationWithKeyPath:@"strokeEnd"];
    animation.duration = 15.0f;
    animation.fromValue = [NSNumber numberWithFloat:0.0f];
    animation.toValue = [NSNumber numberWithFloat:1.0f];
    animation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear];
    [circle addAnimation:animation forKey:@"strokeEnd"];

    [circle release];

    UILabel* label = [[UILabel alloc] init];
    label.text = @"Test Text";
    label.font = [UIFont systemFontOfSize:20.0f];
    label.center = CGPathGetCurrentPoint(path);
    label.transform = CGAffineTransformMakeRotation(1.57079633);
    [label sizeToFit];
    [self.layer addSublayer:label.layer];

    CAKeyframeAnimation* textAnimation = [CAKeyframeAnimation animationWithKeyPath:@"position"];
    textAnimation.duration = 15.0f;
    textAnimation.path = path;
    textAnimation.rotationMode = kCAAnimationRotateAuto;
    textAnimation.calculationMode = kCAAnimationCubicPaced;
    textAnimation.removedOnCompletion = NO;
    [label.layer addAnimation:textAnimation forKey:@"position"];
查看更多
我欲成王,谁敢阻挡
3楼-- · 2019-04-09 03:48

I would suggest creating a new UIView class, and then use the method layoutSubviews.
For more on the UIView class, just have a look at the class reference. Just use something lie this in your main view:

myView = [[myView alloc] initWithFrame:CGRectMake(100,100,100,100)];
[self.view addSubview:myView];

And something like this for layoutSubviews:

- (void) layoutSubviews{
     [super layoutSubviews];

      mainLayer.frame = CGRectMake(0, 0, self.frame.size.width, self.frame.size.height);

      CALayer *circle = [[[CALayer alloc] init] autorelease];
      //You have to set up the circle image and everything
      circle.position = mainLayer.position;
}

Of course, your will have to add the implementation for myView over in your .h, but otherwise everything else should work.

EDIT: Sorry, I forgot to add the text layer code into layoutSubview, but all you to do is create the layer and set its position to mainLayer.position;

查看更多
登录 后发表回答