【问题标题】:Draw UIBezierPaths in UIView without subclassing?在 UIView 中绘制 UIBezierPaths 而不进行子类化?
【发布时间】:2015-06-20 12:09:13
【问题描述】:

我是使用 UIBezierPaths 绘制形状的新手。到目前为止,我发现的所有示例都涉及首先对视图进行子类化,然后覆盖 drawRect: 方法并在其中进行绘图,但是我无法找到任何可以绝对肯定地说这是否是唯一方法的东西在 UIView 中绘制 UIBezierPaths,或者这只是最实用的方式。

有没有其他方法(除了 swizzling)在 UIView 中绘制 UIBezierPath 而不继承它?

【问题讨论】:

    标签: ios objective-c uiview uikit uibezierpath


    【解决方案1】:

    Swift 3 接受的答案:

    let shape = UIBezierPath(ovalIn: view.bounds)
    let shapeLayer = CAShapeLayer()
    shapeLayer.path = shape.cgPath
    shapeLayer.fillColor = UIColor(red: 0.5, green: 1, blue: 0.5, alpha: 1).cgColor
    shapeLayer.strokeColor = UIColor.black.cgColor
    shapeLayer.lineWidth = 2.0
    view.layer.addSublayer(shapeLayer)
    

    【讨论】:

      【解决方案2】:

      已接受答案的 Swift 版本:

          let shape = UIBezierPath(ovalInRect: view.bounds)
          let shapeLayer = CAShapeLayer()
          shapeLayer.path = shape.CGPath
          shapeLayer.fillColor = UIColor(red: 0.5, green: 1, blue: 0.5, alpha: 1).CGColor
          shapeLayer.strokeColor = UIColor.blackColor().CGColor
          shapeLayer.lineWidth = 2.0
          view.layer.addSublayer(shapeLayer)
      

      【讨论】:

        【解决方案3】:

        另一种不使用 drawRect 绘制贝塞尔路径的方法是使用 CAShapeLayers。将形状图层的路径属性设置为从贝塞尔路径创建的 CGPath。将形状层作为子层添加到视图层。

            UIBezierPath *shape = [UIBezierPath bezierPathWithOvalInRect:self.view.bounds];
            CAShapeLayer *shapeLayer = [CAShapeLayer layer];
            shapeLayer.path = shape.CGPath;
            shapeLayer.fillColor = [UIColor colorWithRed:.5 green:1 blue:.5 alpha:1].CGColor;
            shapeLayer.strokeColor = [UIColor blackColor].CGColor;
            shapeLayer.lineWidth = 2;
        
            [self.view.layer addSublayer:shapeLayer];
        

        【讨论】:

        • 这似乎正是我想要的!希望我昨天知道这一点 =P 这样做时 UIBezierPath 是否有任何不可预见的限制或功能无法访问?
        • @n00neimp0rtant 我不知道任何具体的限制,也不知道内存后果会是什么,特别是如果你想拥有多个层。您必须进行一些分析才能找到答案。
        【解决方案4】:

        您可以:1) 将 UIBezierPaths 渲染到图像上下文中。 2) 添加 UIImageView 作为视图的子视图,并使用渲染图像设置图像属性。 像这样的:

        - (void)viewDidLoad {
            [super viewDidLoad];
            self.imageView = [[UIImageView alloc] initWithFrame:self.view.bounds];
            [self.view addSubview:self.imageView];
            [self drawPaths];
        }
        
        - (void)drawPaths {
               UIGraphicsBeginImageContext(self.view.bounds);
               //draw...
               self.imageView.image = UIGraphicsGetImageFromCurrentImageContext();
               UIGraphicsEndImageContext();
        }
        

        【讨论】:

        • 所以你实际上会将贝塞尔路径渲染为 UIImage,然后将其显示在 UIImageView 中?在某些情况下,这可能比子类化更好,但它看起来确实相当昂贵,尤其是在调整视图大小时重绘它时。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-06-03
        • 1970-01-01
        • 2012-03-15
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多