在iPhone上使用Quartz 2D进行基本绘图

时间:2010-05-05 17:28:46

标签: iphone quartz-graphics

我的目标是创建一个程序,只要触摸屏幕就会绘制点。这就是我到目前为止所做的:

标题文件:

#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何时执行?

1 个答案:

答案 0 :(得分:1)

在-touchesEnded:withEvent:中,您有以下代码:

points = (CGRect *)malloc(sizeof(CGRect) * ++npoints);
points[npoints-1] = CGRectMake(lastTouch.x-15, lastTouch.y-15,30,30);

您正在为points重新分配数组,但不会复制以前的任何一点。这导致您使用随机未初始化的内存值而不是您保存的CGRects。相反,尝试以下内容:

CGRect *newPoints = (CGRect *)malloc(sizeof(CGRect) * ++npoints);
for (unsigned int currentPoint = 0; currentPoint < (npoints - 1); currentPoint++)
{
    newPoints[currentPoint] = points[currentPoint];
}
free(points);
points = newPoints;

points[npoints-1] = CGRectMake(lastTouch.x-15, lastTouch.y-15,30,30);

在为其内容分配新数组之前,你还没有释放points数组。

当调用-drawRect:时,当iPhone OS显示系统需要重新调度UIView的内容时会触发它。正如丹尼尔所说,这通常在初始显示时以及在UIView上手动调用-setNeedsDisplay时发生一次。