iOS 5 - 触摸时绘制一个圆圈

时间:2012-05-24 17:47:19

标签: ios ios5 core-graphics

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

这是我现在的代码,它确实搞砸了,我没有任何绘图和使用上下文的练习。我在这里错过了什么?提前致谢。

View controller是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

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

2 个答案:

答案 0 :(得分:4)

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

理想情况下,您应该将drawRect和drawCircleAtPoint放在UIView子类中。 还要在该视图类中添加touches方法。 你可以调用它,DrawCircleView或其他东西。

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

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

<强>更新

您可能希望保存以前绘制的圈子。​​

有很多种可能性,选择最适合你的东西,我没有给你详细解释每一个但足够的信息让你去。

  • 如果您希望圆圈可编辑,则必须继续将有关中心和半径的圆圈信息添加为NSMutableArray 中的一个对象。 在drawRect的开头,你将不得不在循环中重绘所有这些。

    事实上,我建议您使用CGPath 继续向该路径添加圈子,并在drawRect中添加cgcontext的路径,将CGPath保留为实例var,以便保留来自上次drawRect调用的先前信息。 但是,如果您希望能够使用不同颜色绘制圆圈,那么它们必须位于不同的CGPath中 然后你可以再次将这些带有颜色信息的CGPath添加到一个可变数组中。

OR

  • 如果阵列不断增长,保存并重新绘制所有这些圈子将会影响性能。如果您不想要撤消功能,或者您不想编辑以前的圈子。 然后你可以将drawRect末尾绘制的任何内容保存为imageData,然后将其保存为实例var,并在每次调用drawRect时重绘它,然后在其上绘制一个圆并将图像再次保存到同一个实例中。 / LI>

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

  _savedImage = UIGraphicsGetImageFromCurrentImageContext(); 

在drawRect开头重绘时,如果_savedImage 不是nil 那么,

 [_savedImage drawInRect:rect];

然后你可以围绕你点击的点绘制圆圈。 此外,如果需要,您可以随时将图形保存到实际图像文件中:

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

OR

  • 如果您愿意,可以探索CGContextSaveGState() and CGContextRestoreGState() 它们分别用于推送和弹出上下文。 因此,您可以获取最后一个上下文并重新绘制它,在恢复和保存之间,您可以绘制圆圈。查看此stackOverflow帖子:Saving and restoring CGContext

答案 1 :(得分:3)

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

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

  1. 使用您自己的视图子类UIView,在那里实现drawRect和drawCircle方法
  2. 将XIB中的默认UIView替换为您自己的类(IB - &gt; Identity Inspector - &gt; Custom Class)
  3. 连接事件以检测手指触摸,然后使用[view setNeedsDisplay]强制刷新
  4. 注意:子类化和覆盖UIImageView的drawRect什么都不做 - 它是专门处理的:

      

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