2

我想让我的应用程序绘制一个以触摸坐标为中心的圆。

这是我现在拥有的代码,它肯定是一团糟,我没有任何绘制事物和使用上下文的实践。我在这里想念什么?提前致谢。

视图控制器是 UIViewController 的子类

@implementation ViewController

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
    // Custom initialization
}
return self;
}

- (void)viewDidLoad
{
[super viewDidLoad];
}

- (void)viewDidUnload
{
[super viewDidUnload];
}

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
UITouch *theTouch = [touches anyObject];

[self doSomething];

//[self.view setNeedsDisplay];

}

- (void) drawCircleAtPoint:(CGPoint)point withRadius:(CGFloat)radius inContext:(CGContextRef)context{
UIGraphicsPushContext(context);
CGContextBeginPath(context);
CGContextAddArc(context, point.x, point.y, radius, 0, 2*M_PI, YES);
CGContextFillPath(context);
UIGraphicsPopContext();
}

- (void)drawRect:(CGRect)rect
{
CGPoint point;
CGContextRef context = UIGraphicsGetCurrentContext();
point.x = self.view.bounds.origin.x + self.view.bounds.size.width/2;
point.y = self.view.bounds.origin.y + self.view.bounds.size.height/2;
CGContextSetLineWidth(context, 5.0);
[[UIColor whiteColor] setFill];
[self drawCircleAtPoint:point withRadius:50 inContext:context];

}

@end

在这里,我希望它至少在屏幕中心绘制圆圈,但我什至不能这样做。

4

2 回答 2

4

drawRect 是 UIView 类的一个方法。 它在 ViewController 中不可用,因此不会被调用。

理想情况下,您应该将 drawRect 和 drawCircleAtPoint 放在 UIView 子类中。还要在该视图类中添加触摸方法。你可以叫它,DrawCircleView 什么的。

现在创建这个自定义视图的对象,并将其作为子视图添加到 viewDidLoad 中的 viewcontroller 视图中。

在 touches 方法中调用 setNeedsDisplay 并将 touvh 的点存储在 CGPoint 实例变量中并在 drawRect 中访问它。

更新

您可能想要保存以前绘制的圆圈。

有很多可能性,选择最适合你的,我没有给你详细的解释,但足够的信息让你继续。

  • 如果您希望圆是可编辑的,那么您将不得不继续添加有关中心和半径的圆信息作为NSMutableArray 中的一个对象。并且在您的 drawRect 开始时,您将不得不在一个循环中重绘所有这些。

    事实上,我建议您使用 CGPath继续向该路径添加圆圈,并将路径添加到 drawRect 中的 cgcontext 保持 CGPath 作为实例变量,以便它保留上次 drawRect 调用的先前信息。但是同样,如果您希望能够用不同的颜色绘制圆圈,那么它们必须位于不同的 CGPath 中,那么您可以将这些 CGPath 与对象中的颜色信息再次添加到可变数组中。

或者

  • 如果数组不断增长,保存和重绘所有这些圆圈将阻碍性能。如果您不想要撤消功能或者您不想编辑以前的圈子。然后,您可以将 drawRect 末尾绘制的任何内容保存为 imageData ,然后将其保存为实例 var 并在每次调用 drawRect 时重绘它,然后在其顶部绘制一个圆圈并将图像再次保存到同一实例中。

例如:在 drawRect 结束时,您可以将屏幕图像保存到实例变量 _savedImage 中。

  _savedImage = UIGraphicsGetImageFromCurrentImageContext(); 

并且在 drawRect 的开头重绘时,如果 _savedImage不为零,则

 [_savedImage drawInRect:rect];

然后你可以在你点击的点周围画一个圆圈。此外,如果您愿意,您可以随时将绘图保存到实际图像文件中:

 NSData *imageData = UIImagePNGRepresentation(_savedImage);
[imageData writeToFile:@"imageName.png"];

或者

  • 如果你愿意,你可以探索CGContextSaveGState() and CGContextRestoreGState() 它们分别用于推送和弹出上下文到堆栈。因此,您可以获得最后一个上下文并重新绘制它,在恢复和保存之间,您可以绘制您的圆圈。签出此 stackOverflow 帖子:保存和恢复 CGContext
于 2012-05-24T19:02:51.283 回答
3

drawRect 的方法调用发生在UIView中,而不是在UIViewController中- UIViewController 管理视图,并自己处理委托和其他相关项目。绘图发生在 viewController 的 view 属性中。

在您的情况下,您需要执行以下操作:

  1. 使用您自己的视图子类化 UIView,并在那里实现 drawRect 和 drawCircle 方法
  2. 将 XIB 中的默认 UIView 替换为您自己的类(IB -> Identity Inspector -> Custom Class)
  3. 连接事件以检测手指触摸,然后使用 [查看 setNeedsDisplay] 强制刷新

注意:子类化和覆盖 UIImageView 的 drawRect 什么都不做 - 它是专门处理的:

UIImageView 类经过优化,可以将其图像绘制到显示器上。UIImageView 不会调用 drawRect: 一个子类。如果您的子类需要自定义绘图代码,建议您使用 UIView 作为基类。

于 2012-05-24T19:00:53.963 回答