Масштаб анимации CALayer без размытия - PullRequest
3 голосов
/ 20 июня 2010

У меня есть CALayer, который реализует drawInContext: и рисует простой круг, например:

- (void)drawInContext:(CGContextRef)ctx
{
     CGContextScaleCTM(ctx, DrawingScale, DrawingScale);
     CGContextSetRGBFillColor (ctx, 1, 0, 0, 1);
     CGContextFillEllipseInRect (ctx, LocationRectangle);
}

Я экспериментировал с различными способами увеличения размера моего круга на основе события касания. Я пытался использовать систему UIView beginAnimation и CABasicAnimation's, но все они размывают изображение. В моем чтении я обнаружил, что это потому, что CALayer, похоже, обрабатывается как растровые изображения для этих опций.

Достаточно справедливо ... но я хочу масштабировать графику без размытия, например, использовать векторное масштабирование.

Таким образом, в моем коде у меня есть свойство DrawingScale.

Есть ли удобный способ масштабирования этого свойства с помощью анимации слоев? Или это то, что люди делают с NSTimers (юк)?

Может ли это быть одной из ситуаций, когда я могу использовать способность Core Animation для анимации пользовательских свойств? Если это так, я хотел бы знать, какой пример люди считают лучшим, или какой раздел документации Apple может быть хорошим местом для начала этой темы.

Похоже, когда речь заходит о графике на Mac / iOS, есть много способов сделать из кожи / нарисовать кота ...?

Ответы [ 2 ]

3 голосов
/ 23 июня 2010

Проведя несколько дней, работая над этим, одно решение, которое у меня есть, состоит в том, чтобы иметь переменную с именем DrawingScale в качестве переменной-члена (так они называются в Obj-C) и использовать Core Animation для анимации этого свойства.

- (void)drawInContext:(CGContextRef)ctx
{
    CGFloat size = (CGFloat)(DrawingScale*DEFAULT_SIZE);
    CGRect elipseRect = CGRectMake(xPos, yPos, size, size);
    CGContextStrokeEllipseInRect(ctx, elipseRect);
    CGContextFillEllipseInRect (ctx, elipseRect);
}

Затем на событии я настроил анимацию так:

-(void) : (CGPoint) location
{
    /* Set up an explicit animation to scale the players size up */
    CABasicAnimation* anim = [CABasicAnimation animationWithKeyPath:@"DrawingScale"];
    anim.fromValue = [NSNumber numberWithFloat: 1];
    anim.toValue = [NSNumber numberWithFloat: 5];
    anim.removedOnCompletion = YES;
    anim.duration = 0.1;
    anim.delegate = self;
    anim.fillMode = kCAFillModeForwards;
    anim.autoreverses = NO;
    [self addAnimation: anim forKey:@"ElipseGettingBigger"];
}

Это устанавливает анимацию, чтобы установить мою переменную DrawingScale в диапазоне от 1 до 5, и сделать это в течение 0,1 секунды. Это работает очень хорошо.

Мне нужно было быть осторожным и убедиться, что я тоже соответствующим образом скорректировал границы слоев!

2 голосов
/ 22 июня 2010

Используйте слой формы ( CAShapeLayer ).Вы передаете ему путь, цвет заливки и цвет обводки, и он сохранит все ваши края четкими, независимо от масштаба.Если вам нужен только круг, вы можете просто обмануть и создать слой, радиус угла которого равен половине ширины и высоты (при условии идеального квадрата / круга).Примерно так:

CALayer *layer = [CALayer layer];
[layer setMasksToBounds:YES];
[layer setBackgroundColor[[UIColor redColor] CGColor]];
[layer setCornerRadius:25.0f];
[layer setBounds:CGRectMake(0.0f, 0.0f, 50.0f, 50.0f)];
[layer setPosition:CGPointMake([view bounds].size.width/2.0f, 
                               [view bounds].size.height/2.0f]);

[[view layer] addSublayer:layer];

Возможно, вы также захотите взглянуть на последние видео WWDC от Apple .Там есть три сессии по основной анимации.Масштаб обсуждаемого слоя и четкость краев.Видео бесплатно.

С уважением.

...