Как изменить размер CAGradientLayer после ротации?

Я добавляю CAGradientLayer к представлению. Когда просмотр автоматически изменяется (например, после поворота), уровень градиента не изменяется. Можно ли задать градиент для автоматического изменения размера так же, как и для представления? Также обратите внимание, что в представлении я использую ограничения автоматической компоновки.

Вот что я делаю:

    CAGradientLayer *gradientLayer = [CAGradientLayer layer];
    gradientLayer.frame = CGRectMake(0.0, 0.0, frame.size.width, frame.size.height);
    gradientLayer.colors = [NSArray arrayWithObjects:
                       (id)[[UIColor colorWithRed:255.0/255.0f green:255.0/255.0f blue:255.0/255.0f alpha:1.0f] CGColor],
                       (id)[[UIColor colorWithRed:233.0/255.0f green:233.0/255.0f blue:233.0/255.0f alpha:1.0f] CGColor], nil];

    [self.layer insertSublayer:gradientLayer atIndex:0];

Ответ 1

Вот два разных способа исправить вашу проблему.

  • Сделайте gradientLayer переменную экземпляра вместо локальной переменной. Затем переопределите layoutSubviews в вашем классе вида, чтобы установить кадр слоя градиента:

    - (void)layoutSubviews {
        [super layoutSubviews];
        _gradientLayer.frame = self.bounds;
    }
    
  • Создайте подкласс UIView с именем GradientView и переопределите его метод +layerClass, чтобы вернуть [CAGradientLayer class]. Используйте этот вид, чтобы нарисовать свой градиент вместо прямого использования слоя. Затем установите представление градиента autoresizingMask (или добавьте ограничения к нему, если вы используете автоматическую компоновку). См. этот ответ для примера.

Создание класса GradientView также приведет к правильному изменению размера во время вращения, поэтому я рекомендую это решение.

Ответ 2

Я изменяю размер границ слоя вручную, переопределяя метод setFrame: представления:

-(void)setFrame:(CGRect)frame
{
    [super setFrame:frame];
    _gradientLayer.bounds = CGRectMake(0, 0, CGRectGetWidth(frame), CGRectGetHeight(frame));
}