在xCode中创建类似于太阳天气应用程序的动态渐变背景

13
尽管我之前已经问过这个问题,但我想再次联系你以澄清我希望通过你的帮助实现什么。我想知道如何在xCode中创建一个类似于Solar天气应用程序(提供了截屏)的背景,它会随着时间的推移略微变化(循环)。正如您所看到的渐变非常平滑,显然包含不止两个主要点。非常感谢任何带有示例或代码片段的帮助。再次感谢,Ben。 屏幕截图1 屏幕截图2
2个回答

16

我需要的是:

  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合并。

如何在哪里实现3b? - Ben Leather
1
当按照您所说的实现此代码时,会出现许多错误:例如使用了未声明的标识符“topColor”;在对象类型“View Controller *”上未找到属性“bounds”。 - Ben Leather
3
是的,这只是一小段描述关键点的代码,可以帮助你解决问题;它不是一个框架或完整的类,不能直接使用。你需要填写缺失的部分,比如颜色,并适当定义你的类,以便它能够在你的应用程序中以合理的方式使用提供的代码片段(我不知道你的应用程序,所以我无法为你完成)。 - sergio
我已经编辑了问题,以更清晰地描述我需要帮助的内容。 - Ben Leather
@sergio,我该如何在Swift中实现重复动画过程?谢谢。 - DrPatience
显示剩余3条评论

13

简单的工作示例:

.h文件

@property (strong, nonatomic) CAGradientLayer *gradient;

.m文件

- (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"];
}

你可能想要实现一个额外的方法来改变颜色,然后重新运行动画以呈现变化。但这应该会帮助你实现目标。


我已经成功地在Swift中应用了它,但是当动画完成后,它会改回第一种颜色。我该如何将这行代码转换为Swift:[self.gradient setColors:toColors]?谢谢。 - DrPatience
2
简单:self.gradient.colors = toColors - TheTiger
在你的 viewDidAppear 中调用 super 也是一个很好的实践。 - smaili

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接