我尝试编写自己的自定义类来做一些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>
时,它什么都没有。它没有任何吸引力?我检查调试模式,我发现上下文不为空。我问为什么?
答案 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: