Создание анимированного фона градиента, аналогичного приложению Солнечной погоды в xCode

Несмотря на то, что я задал этот вопрос раньше, я хотел бы снова обратиться к вам, чтобы уточнить, что я хотел бы сделать с вашей помощью. Мне было интересно, как создать фоновое приложение iOS в xCode, аналогичное фону приложения Solar weather (снимки экрана), который немного меняется со временем (в цикле). Как вы видите, градиент очень плавный и, очевидно, содержит более двух основных моментов. Любая помощь с примером или фрагментами кода будет принята с благодарностью. Еще раз спасибо, Бен.

Screenshot 1Screenshot 2

Ответы

Ответ 1

Что мне нужно:

  • добавление CAGradientLayer к вашему контроллеру вида (или пользовательскому представлению), например:

    @property (nonatomic, retain) CAGradientLayer *gradient;
    
  • В вашем представлении контроллер, в viewDidLoad, создает и добавляет слой градиента к вашему представлению:

    self.gradient = [CAGradientLayer layer];
    gradient.frame = self.view.bounds;
    gradient.colors = [NSArray arrayWithObjects:
                   (id)topColor.CGColor,
                   (id)bottomColor.CGColor,
                   nil];
    gradient.locations = [NSArray arrayWithObjects:
                      [NSNumber numberWithFloat:0.0f],
                      [NSNumber numberWithFloat:0.7],
                      nil];
    [self.view.layer addSublayer:self.gradient];
    

    3a. добавьте NSTimer к контроллеру, который будет обновлять self.gradient через определенные промежутки времени, выполнив следующие действия:

      topColor = ...; bottomColor = ...;
      NSArray* newColors = [NSArray arrayWithObjects:
                     (id)topColor.CGColor,
                     (id)bottomColor.CGColor,
                     nil];
     [(CAGradientLayer *)self.layer setColors:newColors];
    

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

    3b. добавьте анимацию, подобную этой,

    - (void)animateLayer... {
    
      [UIView animateWithDuration:duration 
                            delay:0
                          options:UIViewAnimationOptionCurveEaseInOut
                       animations:^{
        [CATransaction begin];
        [CATransaction setAnimationDuration:duration];
    
          topColor = ...; bottomColor = ...;
          NSArray* newColors = [NSArray arrayWithObjects:
                     (id)topColor.CGColor,
                     (id)bottomColor.CGColor,
                     nil];
         [(CAGradientLayer *)self.layer setColors:newColors];
    
         [CATransaction commit];
      }
              completion:^(BOOL b) {
                  [self animateLayer..];
              }];
    }
    

Вы также можете комбинировать 3a и 3b.

Ответ 2

Простой рабочий пример:

.h файл

@property (strong, nonatomic) CAGradientLayer *gradient;

.m file

- (void)viewDidAppear:(BOOL)animated
{
    [super viewDidAppear: animated];

    self.gradient = [CAGradientLayer layer];
    self.gradient.frame = self.view.bounds;
    self.gradient.colors = @[(id)[UIColor purpleColor].CGColor,
                             (id)[UIColor redColor].CGColor];

    [self.view.layer insertSublayer:self.gradient atIndex:0];

    [self animateLayer];
}

-(void)animateLayer
{

    NSArray *fromColors = self.gradient.colors;
    NSArray *toColors = @[(id)[UIColor redColor].CGColor,
                          (id)[UIColor orangeColor].CGColor];

    [self.gradient setColors:toColors];

    CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"colors"];

    animation.fromValue             = fromColors;
    animation.toValue               = toColors;
    animation.duration              = 3.00;
    animation.removedOnCompletion   = YES;
    animation.fillMode              = kCAFillModeForwards;
    animation.timingFunction        = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear];
    animation.delegate              = self;

    // Add the animation to our layer

    [self.gradient addAnimation:animation forKey:@"animateGradient"];
}

Возможно, вам захочется реализовать дополнительный метод для изменения цветов, а затем реанимировать изменения. Но это должно помочь вам добраться.