Комбинация CoreAnimation CALayer и CATextLayer

Я просто играю с CA в последнее время. Теперь я как-то застрял. Это то, что я хочу оживить: введите здесь описание изображения

На данный момент у меня уже работает анимация круга. Я создал подкласс CALayer для создания анимации. Я действительно не знаю, куда идти отсюда. Где мне добавить подслой CATextLayer? Как мне анимировать оба одновременно, чтобы текст с его линией прилипал к концу круга?

Если вам нужен код или что-то еще, дайте мне знать.

Буду очень рад получить здесь помощь :-)

Большое спасибо!


person danielreiser    schedule 30.10.2011    source источник
comment
Проверьте ссылку ниже. Хорошая иллюстрация того, что можно сделать с помощью анимации. Они включают в анимацию некоторую физику и т. д. watchingapple.com/2008/04/ ------ edit: А из вашего вопроса непонятно, что вы анимируете. Что такое круговая анимация?... Какое свойство вы анимируете?   -  person debleek63    schedule 08.11.2011
comment
Спасибо! Звучит здорово. Я посмотрю на это. Я хочу анимировать toValue, чтобы endDegree круга.   -  person danielreiser    schedule 08.11.2011


Ответы (2)


Я смог сделать то, о чем вы просите ниже. Код очень грубый, просто потратил на него пару минут, возможно, пропустил выпуски и что у вас есть. Вы можете просто поменять UILabel на CATextLayer (для краткости используется UILabel).

    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"];
person jin    schedule 10.11.2011
comment
Эй, Джин, большое спасибо. Это не совсем тот эффект, которого я хотел (я хотел, чтобы метка оставалась горизонтальной. Но это действительно помогает мне. Если хотите, можете добавить код для этого :-P - person danielreiser; 14.11.2011
comment
Извините за задержку ответа. Если вы удалите эти две линии, label.transform = CGAffineTransformMakeRotation(1.57079633); textAnimation.rotationMode = kCAAnimationRotateAuto;, они останутся горизонтальными. - person jin; 23.11.2011

Я бы предложил создать новый класс UIView, а затем использовать метод layoutSubviews.
Чтобы узнать больше о классе UIView, просто взгляните на ссылка на класс. Просто используйте что-нибудь в своем основном представлении:

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

И что-то вроде этого для 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;
}

Конечно, вам придется добавить реализацию для myView в ваш .h, но в остальном все должно работать.

РЕДАКТИРОВАТЬ: Извините, я забыл добавить код текстового слоя в layoutSubview, но все, что вам нужно сделать, это создать слой и установить его позицию в mainLayer.position;

person Andy B    schedule 05.11.2011
comment
Спасибо за Ваш ответ. Но у меня проблема с анимацией всех вещей. Я уже выполнил рисунок. Я не уверен, куда мне следует вставить CATextLayer для анимации. - person danielreiser; 08.11.2011