Автоматическое изменение размера CALayer на iPhone / iPad: как? - PullRequest
21 голосов
/ 09 сентября 2010

Я пытаюсь создать подкласс UIView ("GradientView"), который будет заполняться градиентом различных цветов. Я реализовал это, добавив CAGradientLayer в качестве подслоя слоя UIView.

Выглядело хорошо, но при повороте экрана размер градиентного слоя не изменился. Не имея возможности найти свойство BOOL на слое для переключения, я переопределил layoutSubviews в GradientView.

-(void)layoutSubviews {
    self.gradientLayer.frame = self.bounds;
}

Это работает, но материал за GradientView все еще виден во время анимации вращения устройства. Какой самый простой способ «автоматически изменить размер» этого CAGradientLayer, чтобы он соответствовал границам своего родительского слоя, чтобы анимация была плавной (как для автоматического изменения размера UIView)?

Ответы [ 5 ]

29 голосов
/ 06 ноября 2010

Вы, вероятно, можете обойтись без определения метода + layerClass для пользовательского UIView ...

@implementation MyGradientView
+(Class) layerClass {
    return [CAGradientLayer class];
}
@end

Вы можете инициализировать слой в viewDidLoad () (или где угодно) вашего контроллера, что-то вроде ...

-(void)viewDidLoad {
    [super viewDidLoad];
    [(CAGradientLayer*)[mMyGradientViewInstance layer] setColors:nil];
}
4 голосов
/ 16 октября 2010

Я бы:

  1. Увеличьте размер вашего представления до максимум из каждого в коде willRotateToInterfaceOrientation. (Например, для iPhone 320x480 - установите яркость 480x480).

  2. Установите границы в соответствии с вновь повернутым видом в функции didRotateFromInterfaceOrientation.

Это должно сделать так, чтобы представление было достаточно большим, чтобы независимо от того, как оно было ориентировано во время анимации, оно охватывало весь экран. Это не будет «гладко» - потому что градиент придется вращать, но, по крайней мере, вы не увидите позади слоя в середине вращения.

2 голосов
/ 20 октября 2010
- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration {

    CGRect b;

    if(UIInterfaceOrientationIsLandscape(toInterfaceOrientation))b = CGRectMake(0, 0, 480, 320);
    else b = CGRectMake(0, 0, 320, 480);    

    [CATransaction begin];
    [CATransaction setValue:[NSNumber numberWithFloat:duration] forKey:kCATransactionAnimationDuration];
    [self.view.layer setBounds:b];
    [CATransaction commit];

}
1 голос
/ 26 января 2012

Обратите внимание, что возврат CAGradientLayer в качестве класса слоя работает только в том случае, если вы установили прозрачный цвет фона представления.Вам нужно будет установить цвет фона слоя, если вам нужен цвет, отличный от прозрачного.

0 голосов
/ 13 марта 2012

в моем случае это работа:

[[[view.layer sublayers] objectAtIndex:gradientIndex] setFrame:view.bounds];
...