【问题标题】:Showing UIBezierPath on view在视图中显示 UIBezierPath
【发布时间】:2010-07-28 11:13:49
【问题描述】:

在我的一种方法中,我有以下代码:

-(void)myMethod {   
   UIBezierPath *circle = [UIBezierPath
                       bezierPathWithOvalInRect:CGRectMake(75, 100, 200, 200)];  
}

如何让它显示在视图上?

我尝试了 addSubview,但它给了我一个 incompatible type error,因为它需要一个 UIView。

我相信这一定很简单。

谢谢

【问题讨论】:

    标签: cocoa-touch uikit uiview


    【解决方案1】:

    只是想补充一点,您不必在 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);
    

    UIGraphicsBeginImageContextWithOptions(size, opaque, scale);
    

    这将为 Retina 和非 Retina 显示器正确绘制图形。

    仅供参考,UIGraphicsBeginImageContext(size) 等同于 UIGraphicsBeginImageContextWithOptions(size, FALSE, 1.f),这对于可能具有一定透明度的非视网膜显示器来说很好。

    但是,如果您不需要透明度,则为 opaque 参数传入 TRUE 会更加优化。

    最安全和推荐的绘图方式是传入[[UIScreen mainScreen]scale] 作为比例参数。

    因此,对于上面的示例,您可以改用这个:

    UIGraphicsBeginImageContextWithOptions(aSize, FALSE, [[UIScreen mainScreen] scale]);
    

    欲了解更多信息,请查看Apple's docs

    【讨论】:

    • 简单、简洁、有用的解释; +1。
    【解决方案2】:

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

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

    【讨论】:

    • 我试过这个,但没有任何反应。如何在我的自定义视图中进行绘图?
    • 创建 UIView 子类并在那里实现 drawRect 方法,它至少对我有用
    • 这是旧的,但如果它对其他人有帮助:我忘记指定我在 Interface Builder 中的视图类型为“MyView”(类标识)
    【解决方案3】:

    您还可以使用 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];
    

    【讨论】:

      【解决方案4】:

      绘图是视图的专有提供。创建一个自定义视图,为其指定路径,然后实现视图的 drawRect: 方法来填充和/或描边路径。

      【讨论】:

      • 所以我制作了一个自定义视图,然后在我的另一个视图控制器 JogShuttle *js = [[JogShuttle alloc] initWithFrame:CGRectMake(...)]; [self.view addSubView:js]; 中执行此操作,但视图上没有绘制任何内容?
      • 你能再贴一些代码吗?你为你的js视图设置了什么框架?检查您的贝塞尔路径是否在视图范围内?
      • 只是感兴趣 - 实际上问题是什么?
      • 我使用的是描边,但没有设置 lineWidth。哇!
      • joec:你不应该这样做。线宽默认为 1.0(与 AppKit、Quartz 和 PostScript 中相同)。
      【解决方案5】:

      在 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)
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多