在视图上显示UIBezierPath

8
在我的一个方法中,我有以下代码:
-(void)myMethod {   
   UIBezierPath *circle = [UIBezierPath
                       bezierPathWithOvalInRect:CGRectMake(75, 100, 200, 200)];  
}

我该如何让它在视图上显示?
我尝试使用addSubview,但它给了我一个不兼容的类型错误,因为它期望一个UIView。
我相信这一定很简单。
谢谢
5个回答

27
只是想补充一下,您不必一定要在UIView的“drawRect:”方法中绘制它。只要您在UIGraphics图像上下文中进行绘制即可。当我不想创建UIView子类时,我经常这样做。以下是一个有效的示例:
UIBezierPath *circle = [UIBezierPath
                        bezierPathWithOvalInRect:CGRectMake(75, 100, 200, 200)];  

//you have to account for the x and y values of your UIBezierPath rect
//add the x to the width (75 + 200)
//add the y to the height (100 + 200)
UIGraphicsBeginImageContext(CGSizeMake(275, 300));

//this gets the graphic context
CGContextRef context = UIGraphicsGetCurrentContext();

//you can stroke and/or fill
CGContextSetStrokeColorWithColor(context, [UIColor blueColor].CGColor);
CGContextSetFillColorWithColor(context, [UIColor lightGrayColor].CGColor);
[circle fill];
[circle stroke];

//now get the image from the context
UIImage *bezierImage = UIGraphicsGetImageFromCurrentImageContext();

UIGraphicsEndImageContext();

UIImageView *bezierImageView = [[UIImageView alloc]initWithImage:bezierImage];

现在将UIImageView添加为子视图。
此外,您还可以将其用于其他绘图。同样,在进行一些设置后,它的工作方式就像drawRect:方法一样。
//this is an arbitrary size for example
CGSize aSize = CGSizeMake(50.f, 50.f);

//this can take any CGSize
//it works like the frame.size would in the drawRect: method
//in the way that it represents the context's size
UIGraphicsBeginImageContext(aSize);

//this gets the graphic context
CGContextRef context = UIGraphicsGetCurrentContext();

//you can do drawing just like you would in the drawRect: method
//I am drawing a square just for an example to show you that you can do any sort of drawing in here
CGContextMoveToPoint(context, 0.f, 0.f);
CGContextAddLineToPoint(context, aSize.width, 0.f);
CGContextAddLineToPoint(context, aSize.width, aSize.height);
CGContextAddLineToPoint(context, 0.f, aSize.height);
CGContextClosePath(context);

//you can stroke and/or fill
CGContextSetStrokeColorWithColor(context, [UIColor blueColor].CGColor);
CGContextSetFillColorWithColor(context, [UIColor lightGrayColor].CGColor);
CGContextDrawPath(context, kCGPathFillStroke);

//now get the image from the context
UIImage *squareImage = UIGraphicsGetImageFromCurrentImageContext();

UIGraphicsEndImageContext();

UIImageView *squareImageView = [[UIImageView alloc]initWithImage:squareImage];

编辑:我应该补充的一件事是,对于任何现代的绘图,你都应该更换
UIGraphicsBeginImageContext(size);

for

UIGraphicsBeginImageContextWithOptions(size, opaque, scale);

这将正确地为Retina和非Retina显示器绘制您的图形。
FYI,UIGraphicsBeginImageContext(size)等同于UIGraphicsBeginImageContextWithOptions(size, FALSE, 1.f),适用于可能具有一些透明度的非Retina显示器。
然而,如果您不需要透明度,则将TRUE传递给opaque参数更为优化。
最安全和推荐的绘制方式是将[[UIScreen mainScreen]scale]作为比例参数传递。
因此,对于上面的示例,您将使用以下内容:
UIGraphicsBeginImageContextWithOptions(aSize, FALSE, [[UIScreen mainScreen] scale]);

更多信息请查看苹果文档

简单、简洁、有用的解释;+1。 - Stian Høiland

18

您可以使用fillstroke方法之一来绘制它,例如在自定义视图的drawInRect:实现中:

- (void)drawRect:(CGRect)rect {
    // Drawing code
    UIBezierPath *circle = [UIBezierPath
                    bezierPathWithOvalInRect:CGRectMake(75, 100, 200, 200)];  
    [circle fill];
}

我尝试了这个,但是没有任何反应。我该如何让绘图在我的自定义视图中发生? - joec
1
创建UIView子类并在其中实现drawRect方法,这对我至少起作用。 - Vladimir
2
这可能有些过时了,但如果能帮到其他人的话:我忘记指定我的 Interface Builder 视图类型为“MyView”(类标识)。 - Mirkules

10

通过使用CAShapeLayer,您可以在不需要创建子类的情况下将UIBezierPath添加到UIView中。

例如,要将路径作为在UIView中居中的3pt白色线添加:

UIBezierPath *mybezierpath = [UIBezierPath
                    bezierPathWithOvalInRect:CGRectMake(0, 0, 100, 100)];  

CAShapeLayer *lines = [CAShapeLayer layer];
lines.path = mybezierpath.CGPath;
lines.bounds = CGPathGetBoundingBox(lines.path);
lines.strokeColor = [UIColor whiteColor].CGColor;
lines.fillColor = [UIColor clearColor].CGColor; /*if you just want lines*/
lines.lineWidth = 3;
lines.position = CGPointMake(self.myview.frame.size.width/2.0, self.myview.frame.size.height/2.0);
lines.anchorPoint = CGPointMake(.5, .5);

[self.myview.layer addSublayer:lines];

3

绘图是视图的独有功能。创建一个自定义视图,将其路径指定为你想要的形状,并实现该视图的drawRect:方法以填充和/或描边路径。


所以我创建了一个自定义视图,然后在其他的视图控制器中添加了这个代码 JogShuttle *js = [[JogShuttle alloc] initWithFrame:CGRectMake(...)]; [self.view addSubView:js]; 但是视图上没有绘制出任何东西? - joec
你能发一些更多的代码吗?你将js视图设置为什么框架?检查一下你的贝塞尔路径是否在视图边界内? - Vladimir
只是好奇 - 实际上问题是什么? - Vladimir
我一直在使用stroke,但没有设置lineWidth。哎呀! - joec
joec:你不需要这样做。行宽默认为1.0(与AppKit、Quartz和PostScript相同)。 - Peter Hosey

2

在Swift 2.0中:

let path = UIBezierPath()

let p1 = CGPointMake(0,self.view.frame.height/2)
let p3 = CGPointMake(self.view.frame.width,self.view.frame.height/2)

path.moveToPoint(p1)
path.addQuadCurveToPoint(p3, controlPoint: CGPoint(x: self.view.frame.width/2, y: 0))

let line = CAShapeLayer()
line.path = path.CGPath;
line.strokeColor = UIColor.blackColor().CGColor
line.fillColor = UIColor.redColor().CGColor
view.layer.addSublayer(line)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接