首页 > 解决方案 > 使用 UIBezierPath 的平行四边形视图

问题描述

我正在尝试使用UIBezierPath但没有得到完美的创建自定义平行四边形视图。

以下是我的自定义视图代码

class CustomView: UIView {
    override func draw(_ rect: CGRect) {
        let offset  = 60.0;
        let path = UIBezierPath()

           path.move(to: CGPoint(x: self.frame.origin.x + CGFloat(offset), y: self.frame.origin.y))
           path.addLine(to: CGPoint(x: self.frame.width + self.frame.origin.x  , y: self.frame.origin.y))
           path.addLine(to: CGPoint(x: self.frame.origin.x + self.frame.width - CGFloat(offset) , y: self.frame.origin.y + self.frame.height))
           path.addLine(to: CGPoint(x: self.frame.origin.x, y: self.frame.origin.y + self.frame.height))


        // Close the path. This will create the last line automatically.
         path.close()
        UIColor.red.setFill()
        path.fill()

        let shapeLayer = CAShapeLayer()
        shapeLayer.path = path.cgPath
        self.layer.mask = shapeLayer;

    }
}

我使用创建视图

let customView = CustomView()
customView.frame = CGRect(origin: CGPoint(x: 10, y: 20), size: CGSize(width: 250, height: 250))
self.view.addSubview(customView)

但我得到了这样的观点,它不是一个完美的平行四边形。

在此处输入图像描述

标签: iosswiftuiviewswift4uibezierpath

解决方案


问题是 inside 的frame使用draw(_:)。问题在于“视图在其父视图的坐标系中frame的大小和位置”(强调添加)。您如何在此视图中渲染此形状通常与此视图在其父视图中的位置无关。如果此视图恰好不在其父视图的 0、0 处,则您可以体验裁剪。

但也不要使用rect参数。“第一次绘制视图时,这个矩形通常是视图的整个可见边界。但是,在随后的绘图操作中,矩形可能只指定了您视图的一部分。” 如果操作系统决定只需要更新您的CustomView.

改用bounds,它位于视图自己的坐标系中。并且,使用minXminYmaxXmaxY可以稍微简化代码。

@IBDesignable
class CustomView: UIView {

    @IBInspectable var offset:    CGFloat = 60        { didSet { setNeedsDisplay() } }
    @IBInspectable var fillColor: UIColor = .red      { didSet { setNeedsDisplay() } }

    override func draw(_ rect: CGRect) {
        let path = UIBezierPath()

        path.move(to: CGPoint(x: bounds.minX + offset, y: bounds.minY))
        path.addLine(to: CGPoint(x: bounds.maxX, y: bounds.minY))
        path.addLine(to: CGPoint(x: bounds.maxX - offset, y: bounds.maxY))
        path.addLine(to: CGPoint(x: bounds.minX, y: bounds.maxY))

        // Close the path. This will create the last line automatically.
        path.close()
        fillColor.setFill()
        path.fill()
    }

}

在此处输入图像描述

顺便说一句,我没有设置面具。draw如果您正在制作动画,那么每次调用时不断重置蒙版似乎效率低下。我个人只是将视图的背景颜色设置为.clear. 但这与当前的问题无关。


推荐阅读