sna*_*ewa 0 drawing uiview cgcontext drawrect
很难说我上传图片来显示我的问题:http://i42.tinypic.com/2eezamo.jpg
基本上在drawRect中,我将从touchesMoved中绘制线条作为手指触摸,我将调用"needsDisplayInRect"进行重绘.但是我发现第一行已经完成,第二行将清除rect部分,因此一些previouse绘图已经消失.
这是我的实现:
enter code here
-(void) drawRect:(CGRect)rect{
//[super drawRect: rect];
CGContextRef context = UIGraphicsGetCurrentContext();
[self drawSquiggle:squiggle at:rect inContext:context];
}
- (void)drawSquiggle:(Squiggle *)squiggle at:(CGRect) rect inContext:(CGContextRef)context
{
CGContextSetBlendMode(context, kCGBlendModeMultiply);
UIColor *squiggleColor = squiggle.strokeColor; // get squiggle's color
CGColorRef colorRef = [squiggleColor CGColor]; // get the CGColor
CGContextSetStrokeColorWithColor(context, colorRef);
NSMutableArray *points = [squiggle points]; // get points from squiggle
// retrieve the NSValue object and store the value in firstPoint
CGPoint firstPoint; // declare a CGPoint
[[points objectAtIndex:0] getValue:&firstPoint];
// move to the point
CGContextMoveToPoint(context, firstPoint.x, firstPoint.y);
// draw a line from each point to the next in order
for (int i = 1; i < [points count]; i++)
{
NSValue *value = [points objectAtIndex:i]; // get the next value
CGPoint point; // declare a new point
[value getValue:&point]; // store the value in point
// draw a line to the new point
CGContextAddLineToPoint(context, point.x, point.y);
} // end for
CGContextStrokePath(context);
}
Run Code Online (Sandbox Code Playgroud)
我尝试实现这一点,但似乎它不能像我预期的那样工作.每次在视图上调用setNeedsDisplay时,我都实现了一个绘制正方形的视图.我将CGImageRef图像和CGBitmapContextRef上下文放入ivar并在视图中分配它们.
#import "View.h"
@implementation View
#define bitsPerComponent 8
#define bitsPerPixel 4*bitsPerComponent
#define bytesPerPixel 4
- (id)initWithFrame:(CGRect)frame {
if ((self = [super initWithFrame:frame])) {
lastPoint = CGPointMake(50, 50);
size_t width = frame.size.width;
size_t height = frame.size.height;
CFMutableDataRef data = CFDataCreateMutable( NULL , width * height * bytesPerPixel );
CGDataProviderRef provider = CGDataProviderCreateWithCFData( data );
CGColorSpaceRef colorspace = CGColorSpaceCreateDeviceRGB();
/*CGImageRef - ivar */ image = CGImageCreate(width, height, bitsPerComponent, bitsPerPixel, width*bytesPerPixel, colorspace, kCGImageAlphaPremultipliedLast, provider, NULL, NO, kCGRenderingIntentDefault);
/*CGBitmapContextRef - ivar */ context = CGBitmapContextCreate(CFDataGetMutableBytePtr(data), width, height, bitsPerComponent, width*bytesPerPixel , colorspace, kCGImageAlphaPremultipliedLast);
CFRelease( data ); // retained by provider I think
CGDataProviderRelease( provider ); // retained by image
CGColorSpaceRelease(colorspace);
}
return self;
}
- (void)drawRect:(CGRect)rect {
NSLog(@"test");
CGContextSetFillColorWithColor(context, [[UIColor blueColor] CGColor]);
CGContextFillRect(context, CGRectMake(lastPoint.x, lastPoint.y, 100, 100));
lastPoint = CGPointMake( ((int)lastPoint.x+50) % 380 , ((int)lastPoint.y+50) % 220 );
CGContextDrawImage(UIGraphicsGetCurrentContext(), CGRectMake(0, 0, 100, 100),image);
}
- (void)dealloc {
[super dealloc];
}
@end
Run Code Online (Sandbox Code Playgroud)
由UIGraphicsGetCurrentContext
in 返回的图形上下文由drawRect:
系统拥有,并在绘图过程开始时清除.创建自己的工具CGContext
以记录您的绘图并drawRect:
根据需要将其渲染到上下文中.
创建一个配对CGBitmapContext
并CGImage
引用它们CGDataProvider
并具有相同的大小,颜色空间和其他属性.在您认为合适的时间和方式中绘制上下文,然后drawRect:
使用CGContextDrawImage
它来显示它.
或者,如果您只是执行一系列行,则可以构建CGMutablePath
并将其呈现给系统上下文.
编辑:
查看CGImageCreate
并CGBitmapContextCreate
在各自的头文件中.大多数论点都是一样的.位图上下文需要原始数据指针,而图像需要CGDataProvider.以下是代码外观的草图.最后,您可以绘制到上下文中,然后使用图像渲染到另一个上下文中.
size_t width = 400;
size_t height = 300;
CFMutableDataRef data = CFDataCreateMutable( NULL , width * height * 4 ); // 4 is bytes per pixel
CGDataProviderRef provider = CGDataProviderCreateWithCFData( data );
CGImageRef image = CGImageCreate( width , height , ... , provider , ... );
CGBitmapContextRef context = CGBitmapContextCreate( CFDataGetMutableBytePtr( data ) , width , height , ... );
CFRelease( data ); // retained by provider I think
CGDataProviderRelease( provider ); // retained by image
Run Code Online (Sandbox Code Playgroud)
有很多空白要填写,但这应该让你开始.您可以使用malloc而不是CFData作为缓冲区.