2013-04-12 3 views
1

Я разрабатываю приложение iOS 5.0+ с последним SDK.Нарисуйте лучистый градиент: <Error>: CGContextDrawPath: недопустимый контекст 0x0

Я очень новичок в 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.

ответ

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. 
} 
+0

Спасибо за ваш ответ. Я вижу этот метод 'drawLayer: inContext:', но я не знаю, должен ли я отправлять ему сообщение или нет. – VansFannel

+0

@VansFannel Если вы являетесь делегатом слоев, тогда этот метод будет вызываться для вас, когда слой будет перерисовываться. –

+0

Я добавил фреймворк QuartzCore, а в файле заголовка я добавил '#import ' но я получаю следующую ошибку: 'Невозможно найти объявление протокола для 'CALayerDelegate''. – VansFannel

0

Создайте собственный подкласс UIView, который рисует градиент в своем методе drawRect:, и ваш VC создаст вид радиального градиента и добавит его в качестве подвидности своего представления.

+0

мне нужна 'CALayer', так что я думаю, что сможет реализовать свой ответ, используя лучистый градиент на' рисовать: ', используя пользовательский 'CALayer', не так ли? – VansFannel

+0

@VansFannel: вы можете использовать пользовательский CALayer (в этом случае вы должны выполнить работу в 'drawInContext:'), но зачем вам нужен слой? –

1

UIGraphicsGetCurrentContext() возвращают только допустимый контекст при вызове из sprecific методов или из вас создан новый F.E. по телефону UIGraphicsBeginImageContext().

Так что вам нужно сделать, это либо подкласс UIView и перезаписать его drawRect: метод с кодом в вашем методе drawRadiantGradient. Или вы можете использовать методы делегата, предоставленные протоколом CALayerDelegate. Просто установите делегат слоя на ваш vc и реализуйте метод drawLayer:inContext:. Это может выглядеть так:

в вашем.ч файл:

@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]; 
} 
+0

Я добавил фреймворк QuartzCore, а в файле заголовка я добавил '#import ', но я получаю следующую ошибку: 'Невозможно найти объявление протокола для 'CALayerDelegate''. – VansFannel

+1

CALayerDelegate - неофициальный протокол; вы не можете заявить о соответствии ему. –

+0

Вы правы, я исправил это. – Tobi

Смежные вопросы