如何为我的UIView子类创建CGGradient?

时间:2009-07-17 23:52:53

标签: objective-c cocoa-touch uiview core-graphics

有谁知道如何创建一个 CGGradient 来填充我的观点,
我目前的代码是这个,它用 UIView 填充一个红色矩形我想要一个渐变(例如从黑色到灰色)而不是rect:

- (void)drawRect:(CGRect)rect {
    CGContextRef context=UIGraphicsGetCurrentContext();
    CGRect r;
    r.origin.x=0.;
    r.origin.y=0.;
    r.size.width=rect.size.width;   
    r.size.height=rect.size.height; 
    CGContextSetRGBFillColor(context, 1., 0., 0., 1.);
    CGContextFillRect (context,r);  
}

3 个答案:

答案 0 :(得分:3)

my answerthis question中,我提供了在UIView中绘制光泽渐变的代码。颜色和绘图位置可以从中进行修改,以形成您需要的任何线性渐变。

答案 1 :(得分:3)

这是一个子类,您可以在其中选择颜色

.h文件

#import <UIKit/UIKit.h>

@interface GradientView : UIView {
    CGGradientRef gradient;
}

@property(nonatomic, assign) CGGradientRef gradient;

- (id)initWithGradient:(CGGradientRef)gradient;
- (id)initWithColor:(UIColor*)top bottom:(UIColor*)bot;
- (void)setGradientWithColor:(UIColor*)top bottom:(UIColor*)bot;
- (void)getRGBA:(CGFloat*)buffer;

@end

.m文件

#import "GradientView.h"

@implementation GradientView

@synthesize gradient;

- (id)initWithGradient:(CGGradientRef)grad {
    self = [super init];
    if(self){
        [self setGradient:grad];
    }
    return self;
}

- (id)initWithColor:(UIColor*)top bottom:(UIColor*)bot {
    self = [super init];
    if(self){
        [self setGradientWithColor:top bottom:bot];
    }
    return self;
}

- (void)setGradient:(CGGradientRef)g {
    if(gradient != NULL && g != gradient){
        CGGradientRelease(gradient);
    }
    if(g != gradient){
        CGGradientRetain(g);
    }
    gradient = g;
    [self setNeedsDisplay];
}

- (void)setGradientWithColor:(UIColor*)top bottom:(UIColor*)bot {
    CGColorSpaceRef rgb = CGColorSpaceCreateDeviceRGB();
    CGFloat clr[8];
    [top getRGBA:clr];
    [bot getRGBA:clr+4] ;
    CGGradientRef grad = CGGradientCreateWithColorComponents(rgb, clr, NULL, sizeof(clr)/(sizeof(clr[0])*4));
    [self setGradient:grad];
    CGColorSpaceRelease(rgb);
    CGGradientRelease(grad);
}

- (void)getRGBA:(CGFloat*)buffer {
    CGColorRef clr = [self CGColor];
    NSInteger n = CGColorGetNumberOfComponents(clr);
    const CGFloat *colors = CGColorGetComponents(clr);
    // TODO: add other ColorSpaces support
    switch (n) {
        case 2:
            for(int i = 0; i<3; ++i){
                buffer[i] = colors[0];
            }
            buffer[3] = CGColorGetAlpha(clr);
            break;
        case 3:
            for(int i = 0; i<3; ++i){
                buffer[i] = colors[i];
            }
            buffer[3] = 1.0;
            break;

        case 4:
            for(int i = 0; i<4; ++i){
                buffer[i] = colors[i];
            }
            break;
        default:
            break;
    }
}

- (void)drawRect:(CGRect)rect {
    CGContextRef c = UIGraphicsGetCurrentContext();
    CGContextDrawLinearGradient(c, gradient, CGPointMake(0, 0), CGPointMake(0, rect.size.height), 0);
}


- (void)dealloc {
    CGGradientRelease(gradient);
    [super dealloc];
}


@end

答案 2 :(得分:2)

使用CGGradientCreateWithColorComponentsCGGradientCreateWithColors创建渐变。 (后者使用CGColor对象。)然后,使用CGContextDrawLinearGradientCGContextDrawRadialGradient绘制它。

线性梯度将至少在垂直于梯度线的两个方向上无限延伸。径向梯度在每个方向上无限延伸。为防止渐变溢出视图,您可能需要使用CGContextClipToRect将视图的边界添加到剪切路径。