在 iPhone 上使用 Quartz 2D 进行基本绘图
我的目标是制作一个程序,每当触摸屏幕时都会绘制点。这是我到目前为止所拥有的:
头文件:
#import <UIKit/UIKit.h>
@interface ElSimView : UIView
{
CGPoint firstTouch;
CGPoint lastTouch;
UIColor *pointColor;
CGRect *points;
int npoints;
}
@property CGPoint firstTouch;
@property CGPoint lastTouch;
@property (nonatomic, retain) UIColor *pointColor;
@property CGRect *points;
@property int npoints;
@end
实现文件:
//@synths etc.
- (id)initWithFrame:(CGRect)frame
{
return self;
}
- (id)initWithCoder:(NSCoder *)coder
{
if(self = [super initWithCoder:coder])
{
self.npoints = 0;
}
return self;
}
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
UITouch *touch = [touches anyObject];
firstTouch = [touch locationInView:self];
lastTouch = [touch locationInView:self];
}
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
UITouch *touch = [touches anyObject];
lastTouch = [touch locationInView:self];
points = (CGRect *)malloc(sizeof(CGRect) * ++npoints);
points[npoints-1] = CGRectMake(lastTouch.x-15, lastTouch.y-15,30,30);
[self setNeedsDisplay];
}
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
UITouch *touch = [touches anyObject];
lastTouch = [touch locationInView:self];
[self setNeedsDisplay];
}
- (void)drawRect:(CGRect)rect
{
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSetLineWidth(context, 2.0);
CGContextSetStrokeColorWithColor(context, [UIColor blackColor].CGColor);
CGContextSetFillColorWithColor(context, pointColor.CGColor);
for(int i=0; i<npoints; i++)
CGContextAddEllipseInRect(context, points[i]);
CGContextDrawPath(context, kCGPathFillStroke);
}
- (void)dealloc {
free(points);
[super dealloc];
}
@end
当我加载它并单击某些点时,它会正常绘制第一个点,然后接下来的点与随机椭圆(甚至不是圆形)一起绘制。
另外我还有一个问题:确切drawRect
什么时候执行?
My goal is to make a program that will draw points whenever the screen is touched. This is what I have so far:
The header file:
#import <UIKit/UIKit.h>
@interface ElSimView : UIView
{
CGPoint firstTouch;
CGPoint lastTouch;
UIColor *pointColor;
CGRect *points;
int npoints;
}
@property CGPoint firstTouch;
@property CGPoint lastTouch;
@property (nonatomic, retain) UIColor *pointColor;
@property CGRect *points;
@property int npoints;
@end
The implementation file:
//@synths etc.
- (id)initWithFrame:(CGRect)frame
{
return self;
}
- (id)initWithCoder:(NSCoder *)coder
{
if(self = [super initWithCoder:coder])
{
self.npoints = 0;
}
return self;
}
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
UITouch *touch = [touches anyObject];
firstTouch = [touch locationInView:self];
lastTouch = [touch locationInView:self];
}
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
UITouch *touch = [touches anyObject];
lastTouch = [touch locationInView:self];
points = (CGRect *)malloc(sizeof(CGRect) * ++npoints);
points[npoints-1] = CGRectMake(lastTouch.x-15, lastTouch.y-15,30,30);
[self setNeedsDisplay];
}
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
UITouch *touch = [touches anyObject];
lastTouch = [touch locationInView:self];
[self setNeedsDisplay];
}
- (void)drawRect:(CGRect)rect
{
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSetLineWidth(context, 2.0);
CGContextSetStrokeColorWithColor(context, [UIColor blackColor].CGColor);
CGContextSetFillColorWithColor(context, pointColor.CGColor);
for(int i=0; i<npoints; i++)
CGContextAddEllipseInRect(context, points[i]);
CGContextDrawPath(context, kCGPathFillStroke);
}
- (void)dealloc {
free(points);
[super dealloc];
}
@end
When I load this and click some points, it draws the first points normally, then then next points are drawn along with random ellipses (not even circles).
Also I have another question: When is exactly drawRect
executed?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
在 -touchesEnded:withEvent: 中,您有以下代码:
您正在为
points
重新分配一个数组,但不会复制之前的任何点。这导致您使用随机的未初始化内存值而不是保存的 CGRect。相反,请尝试如下操作:之前您还通过在为其内容分配新数组之前未释放它而泄漏了
points
数组。至于
-drawRect:
被调用的时候,它是在iPhone OS显示系统需要重新缓存UIView的内容时触发的。正如 Daniel 所说,这种情况通常会在初始显示时以及您在 UIView 上手动调用-setNeedsDisplay
时发生一次。In -touchesEnded:withEvent:, you have the following code:
You are re-allocating an array for
points
, but not copying over any of your previous points. This was causing you to use random uninitialized memory values instead of your saved CGRects. Instead, try something like the following:You were also leaking the
points
array before by not freeing it before allocating a new array for its contents.As far as when
-drawRect:
is called, it is triggered when the iPhone OS display system needs to recache the content of a UIView. As Daniel stated, this typically happens once on initial display and whenever you manually call-setNeedsDisplay
on the UIView.