绘制Radiant Gradient:<error>:CGContextDrawPath:无效的上下文0x0 </error>

时间:2013-04-12 07:29:55

标签: ios objective-c core-graphics

我正在使用最新的SDK开发iOS 5.0+应用程序。

我对CoreGraphics非常新,我不知道如何在CALayer上绘制辐射渐变。

我发现我必须使用CGContextDrawRadialGradient来绘制辐射渐变。

在Google上搜索,我发现我必须为CALayer的内容添加辐射渐变,但要绘制它我需要CGContext,而我不知道如何获得此CGContext

你知道我该怎么办?

我找到了这个tutorial,但它也使用了CGContext

我的代码是:

#import <UIKit/UIKit.h>

@interface ViewController : UIViewController

@property (weak, nonatomic) IBOutlet UIView *testView;

@end

实施

#import "ViewController.h"
#import <QuartzCore/QuartzCore.h>

@interface ViewController ()

- (void)drawRadiantGradient;

@end

@implementation ViewController

@synthesize testView = _testView;

- (void)viewDidLoad
{
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
    [self drawRadiantGradient];
}

- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

- (void)drawRadiantGradient
{
    CGContextRef context = UIGraphicsGetCurrentContext();
    CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();

    CGFloat redBallColors[] = {
        1.0, 0.9, 0.9, 0.7,
        1.0, 0.0, 0.0, 0.8
    };
    CGFloat glossLocations[] = {0.05, 0.9};
    CGGradientRef ballGradient = CGGradientCreateWithColorComponents(colorSpace, redBallColors, glossLocations, 2);
    CGRect circleBounds = CGRectMake(20, 250, 100, 100);
    CGPoint startPoint = CGPointMake(50, 270);
    CGPoint endPoint = CGPointMake(70, 300);
    CGContextDrawRadialGradient(context, ballGradient, startPoint, 0, endPoint, 50, 0);
    CGContextAddEllipseInRect(context, circleBounds);
    CGContextDrawPath(context, kCGPathStroke);
}

我想创建一个CALayer,绘制一个辐射渐变,并将此CALayer添加到_testView

3 个答案:

答案 0 :(得分:1)

您可以绘制到自己的上下文中(例如,使用UIGraphicsBeginImageContextWithOptions()

创建的图像上下文

成为该图层的委托,并使用drawLayer:inContext:

绘制到图层图形上下文中

听起来我想要做第二种选择。您将创建CALayer并将自己设置为委托。然后实现drawLayer:inContext:并使用上下文作为参数传递的上下文。

设置

CALayer *yourLayer = [CALayer layer];
// other layer customisation
yourLayer.delegate = self;

并绘制

- (void)drawLayer:(CALayer *)layer inContext:(CGContextRef)ctx {
    // Check that the layer argument is yourLayer (if you are the 
    // delegate to more than one layer)

    // Use the context (second) argument to draw.
}

答案 1 :(得分:1)

UIGraphicsGetCurrentContext()仅在从sprecific方法调用时返回有效上下文,或者您创建了一个新的f.e.致电UIGraphicsBeginImageContext()

所以你需要做的是将UIView作为子类,并使用drawRect:方法中的代码覆盖它的drawRadiantGradient方法。或者您可以使用CALayerDelegate协议提供的委托方法。只需将图层的委托设置为您的vc并实现drawLayer:inContext:方法即可。这看起来像这样:

你的.h文件中的

@interface MyVC : UIViewController
@property (weak, nonatomic) IBOutlet UIView *drawingView;    
/...

并在您的.m文件中:

- (void)viewDidLoad
{
    [super viewDidLoad];
    self.drawingView.layer.delegate = self;
}

- (void)drawLayer:(CALayer *)layer inContext:(CGContextRef)context
{
    [self drawRadiantGradientInContext:context];
}

答案 2 :(得分:0)

创建UIView的自定义子类,在其drawRect:方法中绘制渐变,让VC创建径向渐变视图并将其添加为其视图的子视图。