iOS 渐变色

本文介绍了在iOS中如何利用CAGradientLayer创建渐变色效果,探讨了不能直接在imageView上用CAGradientLayer作为图片背景的问题,并提出通过colorWithPatternImage方法结合渐变色实现背景的解决方案。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

可以直接使用CAGradientLayer来实现渐变色。(android有各种drawable,iOS有各种layer。)

CAGradientLayer * layer = [CAGradientLayer layer];
layer.frame = self.bounds;
UIColor * startColor = [UIColor clearColor];
UIColor * endColor = [UIColor redColor];
layer.colors = [NSArray arrayWithObjects:(id)startColor.CGColor, (id)endColor.CGColor,nil];
[self.layer addSublayer:layer];
不过,对于系统已定义的控件,如UIImageView,image是画在imageView.layer,而新的layer必定是加在原layer的上面。

所以,想在imageView上面直接使用CAGradientLayer作为图片背景,是不可能实现的。


系统为UIColor提供了一个方法,colorWithPatternImage。结合这个方法,我们可以玩出一些花样。下面的代码直接从Chameleon这个类库中复制的。

+ (UIColor *)colorWithGradientStyle:(UIGradientStyle)gradientStyle withFrame:(CGRect)frame andColors:(NSArray *)colors; {
    
    //Create our background gradient layer
    CAGradientLayer *backgroundGradientLayer = [CAGradientLayer layer];
    
    //Set the frame to our object's bounds
    backgroundGradientLayer.frame = frame;
    
    //To simplfy formatting, we'll iterate through our colors array and create a mutable array with their CG counterparts
    NSMutableArray *cgColors = [[NSMutableArray alloc] init];
    for (UIColor *color in colors) {
        [cgColors addObject:(id)[color CGColor]];
    }
    
    switch (gradientStyle) {
        case UIGradientStyleLeftToRight: {
            
            //Set out gradient's colors
            backgroundGradientLayer.colors = cgColors;
            
            //Specify the direction our gradient will take
            [backgroundGradientLayer setStartPoint:CGPointMake(0.0, 0.5)];
            [backgroundGradientLayer setEndPoint:CGPointMake(1.0, 0.5)];
            
            //Convert our CALayer to a UIImage object
            UIGraphicsBeginImageContextWithOptions(backgroundGradientLayer.bounds.size,NO, [UIScreen mainScreen].scale);
            [backgroundGradientLayer renderInContext:UIGraphicsGetCurrentContext()];
            UIImage *backgroundColorImage = UIGraphicsGetImageFromCurrentImageContext();
            UIGraphicsEndImageContext();
        
            [self setGradientImage:backgroundColorImage];
            return [UIColor colorWithPatternImage:backgroundColorImage];
        }
            
        case UIGradientStyleRadial: {
            UIGraphicsBeginImageContextWithOptions(frame.size,NO, [UIScreen mainScreen].scale);
            
            //Specific the spread of the gradient (For now this gradient only takes 2 locations)
            CGFloat locations[2] = {0.0, 1.0};

            //Default to the RGB Colorspace
            CGColorSpaceRef myColorspace = CGColorSpaceCreateDeviceRGB();
            CFArrayRef arrayRef = (__bridge CFArrayRef)cgColors;
            
            //Create our Fradient
            CGGradientRef myGradient = CGGradientCreateWithColors(myColorspace, arrayRef, locations);
            
 
            // Normalise the 0-1 ranged inputs to the width of the image
            CGPoint myCentrePoint = CGPointMake(0.5 * frame.size.width, 0.5 * frame.size.height);
            float myRadius = MIN(frame.size.width, frame.size.height) * 1.0;
            
            // Draw our Gradient
            CGContextDrawRadialGradient (UIGraphicsGetCurrentContext(), myGradient, myCentrePoint,
                                         0, myCentrePoint, myRadius,
                                         kCGGradientDrawsAfterEndLocation);
            
            // Grab it as an Image
            UIImage *backgroundColorImage = UIGraphicsGetImageFromCurrentImageContext();
            
            // Clean up
            CGColorSpaceRelease(myColorspace); // Necessary?
            CGGradientRelease(myGradient); // Necessary?
            UIGraphicsEndImageContext();
            
            [self setGradientImage:backgroundColorImage];
            return [UIColor colorWithPatternImage:backgroundColorImage];
        }
            
        case UIGradientStyleTopToBottom:
        default: {
            
            //Set out gradient's colors
            backgroundGradientLayer.colors = cgColors;
            
            //Convert our CALayer to a UIImage object
            UIGraphicsBeginImageContextWithOptions(backgroundGradientLayer.bounds.size,NO, [UIScreen mainScreen].scale);
            [backgroundGradientLayer renderInContext:UIGraphicsGetCurrentContext()];
            UIImage *backgroundColorImage = UIGraphicsGetImageFromCurrentImageContext();
            UIGraphicsEndImageContext();
            
            [self setGradientImage:backgroundColorImage];
            return [UIColor colorWithPatternImage:backgroundColorImage];
        }
            
    }
}


非常好用的一个UIColor的库。

有了以上的方法,我们可以很方便的为任何的view设置一个渐变色作为背景颜色。



1、波纹动画主要依赖于CAShapeLayer的绘制,使用帧动画实现;需要使用多个CAShapeLayer通过y值变换组成(这里我只是用了2个CAShapeLayer)。 2、渐变色由CAGradientLayer完成。 ``` - (void)changeFirstWaveLayerPath { CGMutablePathRef path = CGPathCreateMutable(); CGFloat y = _wavePointY; CGPathMoveToPoint(path, nil, 0, y); for (float x = 0.0f; x <= _waveWidth; x ) { y = _waveAmplitude * 1.6 * sin((250 / _waveWidth) * (x * M_PI / 180) - _waveOffsetX * M_PI / 270) _wavePointY; CGPathAddLineToPoint(path, nil, x, y); } CGPathAddLineToPoint(path, nil, _waveWidth, 0); CGPathAddLineToPoint(path, nil, 0, 0); CGPathCloseSubpath(path); _shapeLayer1.path = path; CGPathRelease(path); } - (void)changeSecondWaveLayerPath { CGMutablePathRef path = CGPathCreateMutable(); CGFloat y = _wavePointY; CGPathMoveToPoint(path, nil, 0, y); for (float x = 0.0f; x <= _waveWidth; x ) { y = _waveAmplitude * 1.6 * sin((250 / _waveWidth) * (x * M_PI / 180) - _waveOffsetX * M_PI / 180) _wavePointY; CGPathAddLineToPoint(path, nil, x, y); } CGPathAddLineToPoint(path, nil, _waveWidth, 0); CGPathAddLineToPoint(path, nil, 0, 0); CGPathCloseSubpath(path); _shapeLayer2.path = path; CGPathRelease(path); } ``` 方法调用: ``` _waveOffsetX = _waveSpeed; [self changeFirstWaveLayerPath]; [self changeSecondWaveLayerPath]; [self.layer addSublayer:self.gradientLayer1]; self.gradientLayer1.mask = _shapeLayer1; [self.layer addSublayer:self.gradientLayer2]; self.gradientLayer2.mask = _shapeLayer2; ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值