Quartz2d和实例方法

时间:2015-01-06 11:51:51

标签: ios class

我尝试编写自己的自定义类来做一些2D的东西。 (TwoDOperations.h和TwoDOperations.m)。以下是我的文件。

-------- TwoDOperations.h ------

@interface TwoDOperations : UIView
- (void)drawRect:(CGRect)rect withscene:(UIViewController *)sender;
- (void)drawRectV2:(CGRect)rect;
-(instancetype)init;
@end

-------- TwoDOperations.m ------

#import "TwoDOperations.h"

@implementation TwoDOperations

-(instancetype)init{
    self=[super init];
    if (self)
    {
    }
    return self;
}



- (void)drawRect:(CGRect)rect withscene:(UIViewController *)sender{
    UIView *myBox  = [[UIView alloc] initWithFrame:CGRectMake(10, 20, 300, 10)];
    myBox.backgroundColor = [UIColor lightGrayColor];
    [sender.view addSubview:myBox];
    }

- (void)drawRectV2:(CGRect)rect{
    UIBezierPath *circle = [UIBezierPath
                            bezierPathWithOvalInRect:CGRectMake(0, 0, 200, 200)];

    UIGraphicsBeginImageContext(CGSizeMake(200, 200));


    CGContextRef context = UIGraphicsGetCurrentContext();

    CGContextSetStrokeColorWithColor(context, [UIColor blueColor].CGColor);
    CGContextSetFillColorWithColor(context, [UIColor lightGrayColor].CGColor);
    [circle fill];
    [circle stroke];
   }

@end

如你所见,我有两种方法可以做一些2D事情。

我的主要方法是这样的:

TwoDOperations  *twoD = [[TwoDOperations alloc]init];

CGRect  rect = CGRectMake(10,10,10,10);
[twoD drawRect:rect withscene:self];
[twoD drawRectV2:rect];

(我知道现在不使用rect)

当我使用<twoD drawRect:rect with scene:self>时,它已成功绘图。我可以画一个矩形。但是当我使用<twoD drawRectV2:rect>时,它什么都没有。它没有任何吸引力?我检查调试模式,我发现上下文不为空。我问为什么?

1 个答案:

答案 0 :(得分:0)

因为您的drawRectV2:方法确实无效。您正在使用UIGraphicsBeginImageContext(200, 200)创建图像上下文并在此图形上下文中绘制一个圆,但您不使用此绘图的结果。创建图形上下文只是为您提供了一些图形缓冲区(换句话说 - 图形表面),并且您可以绘制到此缓冲区/曲面中。但除非您绘制到iOS视图绘图系统提供的系统上下文,否则您将看不到绘图结果(我的意思是在被覆盖的UIGraphicsGetCurrentContext() UIView中调用drawRect:时获得的上下文方法)。

要在代码中获取绘图结果,您需要调用返回UIGraphicsGetImageFromCurrentImageContext()的{​​{1}}函数。除此之外,如果您调用UIImage函数,则必须调用UIGraphicsBeginImageContext()。请参阅"Drawing and Printing Guide for iOS", "Creating New Images Using Bitmap Graphics Contexts" section,例如使用我上面提到的功能。

但还有另一个问题。假设你通过调用UIGraphicsEndImageContext()来获得你的绘画结果(即UIImage);你将如何处理这个绘图结果,即你将如何使用获得的UIGraphicsGetImageFromCurrentImageContext()

一般来说,UIImage类的实现看起来很奇怪。您似乎需要阅读更多文档来理解iOS视图绘图的概念。我建议你阅读"View Programming Guide for iOS", "Implementing Your Drawing Code" section

我理解你的意图,你想创建一个视图来做一些自定义绘图,例如一个圆圈。如果这种理解是正确的,那么我将以下列方式实现它:

-------- TwoDOperations.h ------

TwoDOperations

-------- TwoDOperations.m ------

@interface TwoDOperations : UIView

// No need to declare anything as we're only going to override UIView's methods

@end

-------- ViewController.m ------

#import "TwoDOperations.h"

@implementation TwoDOperations

- (instancetype)init 
{
    self = [super init];

    if (self != nil) {
        // Custom initialization
        self.backgroundColor = [UIColor lightGrayColor];
    }

    return self;
}

- (void)drawRect:(CGRect)rect
{
    CGContextRef context = UIGraphicsGetCurrentContext();

    CGContextSaveGState(context);

    CGContextSetStrokeColorWithColor(context, [UIColor blueColor].CGColor);
    CGContextSetFillColorWithColor(context, [UIColor lightGrayColor].CGColor);

    UIBezierPath *circle = [UIBezierPath bezierPathWithOvalInRect:rect];
    [circle fill];
    [circle stroke];

    CGContextRestoreGState(context);
}

@end

在上面的示例中,iOS绘图系统自动调用- (void)viewDidLoad { [super viewDidLoad]; CGRect frame = CGRectMake(0, 0, 200, 200); TwoDOperations* twoDOperationsView = [[TwoDOperations alloc] initWithFrame:frame]; [self.view addSubview:twoDOperationsView]; } 的{​​{1}}方法,UIGraphicsGetCurrentContext()为您提供了正确的系统图形上下文。然后,iOS绘图系统从该系统图形上下文中获取绘图结果并将其显示在显示上。你永远不应该自己调用TwoDOperations的绘图方法,只有系统应该这样做。例如,如果您在代码中手动调用drawRect:的{​​{1}}方法,则很可能UIGraphicsGetCurrentContext()不会返回正确的图形上下文,因此无法进行绘制。

更新

根据您对进度条的评论,我正在更新我的答案。

因此,一般来说,您希望自定义视图根据某些外部条件绘制不同的内容。例如。默认情况下,视图应绘制一个矩形(进度条背景)和一个反映默认进度条值的较小矩形;如果用户按下某个按钮,则进度条值会更改,并且应使用新大小重新绘制较小的矩形。在这种情况下,最好的方法是在自定义视图的UIView方法中使用不同的绘图,具体取决于表示进度条值的数据。您不需要有2个视图来表示您的进度条;您只需要在视图控制器的TwoDOperations方法中添加一个视图。然后,当用户按下某些按钮时,您可以更改自定义视图的数据,以便其drawRect:方法将绘制新的进度条。

我将按如下方式实现:

-------- TwoDOperations.h ------

drawRect:

-------- TwoDOperations.m ------

viewDidLoad

-------- ViewController.m ------

drawRect: