【问题标题】:UIBezierPath, how to draw "QuadCurve"UIBezierPath,如何绘制“QuadCurve”
【发布时间】:2020-12-01 12:33:53
【问题描述】:

我正在尝试使用 UIBezierPath 绘制形状,但我不完全了解如何使用“addQuadCurve”,我先从中心圆孔向左绘制曲线但不明白如何绘制右边缘。

我做错了什么?

结果需要什么: 我的结果:

形状代码:

class CustomShapeOfBottomOne: UIView {

    // init the view with a rectangular frame
    override init(frame: CGRect)
    {
      super.init(frame: frame)
      backgroundColor = UIColor.clear
    }
    // init the view by deserialisation
    required init?(coder aDecoder: NSCoder)
    {
      super.init(coder: aDecoder)
      backgroundColor = UIColor.clear
    }

    override func draw(_ rect: CGRect)
    {
        
        let fillColor = UIColor(red: 0.118, green: 0.118, blue: 0.149, alpha: 1.000)
        
        let path = UIBezierPath()
        let viewWidth = frame.width
        let viewHeight = frame.height - 20
        
        path.move(to: CGPoint(x: (viewWidth - viewWidth) + 10, y: 0))
        
        path.addLine(to: CGPoint(x: (viewWidth / 2) - 35 - 10, y: 0))
        
        // center left edge
        
        path.addQuadCurve(to: CGPoint(x: (viewWidth / 2 ) - 35, y: (11/2.0)), controlPoint: CGPoint(x: (viewWidth / 2 ) - 35, y: 0))
        // end left edge
        
        path.addArc(withCenter: CGPoint(x: viewWidth / 2, y: 0), radius: 35, startAngle: CGFloat(Double.pi), endAngle: CGFloat(Double.pi * Double.pi), clockwise: false)
        
        // How to draw this curve?
        
        // center right edge
//        path.addQuadCurve(to: CGPoint(x: (viewWidth / 2 ) + 35 + 10 , y: 0), controlPoint: CGPoint(x: (viewWidth / 2 ) + 35 - 10, y: 10))
        
        
        // end right edge
        
        path.addLine(to: CGPoint(x: viewWidth - 10, y: 0))
                
        path.addArc(withCenter: CGPoint(x: viewWidth - 10, y: (viewHeight - viewHeight) + 10),
                    radius: 10,
                    startAngle: CGFloat(Double.pi / 2), // 90 degree
                    endAngle: CGFloat(0), // 0 degree
                clockwise: true)
        
        path.addLine(to: CGPoint(x: viewWidth, y: (viewHeight - viewHeight) + viewHeight + 10))
        
        path.addArc(withCenter: CGPoint(x:  viewWidth - 10, y: (viewHeight - viewHeight) + viewHeight + 10),
                    radius: 10,
                    startAngle: CGFloat(0), // 360 degree
                endAngle: CGFloat((3 * Double.pi) / 2 ), // 270 degree
                clockwise: true)
        
        path.addLine(to: CGPoint(x: viewWidth - 10, y: (viewHeight - viewHeight) + viewHeight + 10 + 10))
        path.addLine(to: CGPoint(x: (viewWidth - viewWidth) + 10, y: (viewHeight - viewHeight) + viewHeight + 10 + 10))
        
        path.addArc(withCenter: CGPoint(x: (viewWidth - viewWidth) + 10, y: (viewHeight - viewHeight) + viewHeight + 10),
                    radius: 10,
                    startAngle: CGFloat((3 * Double.pi) / 2), // 270 degree
                    endAngle: CGFloat(Double.pi ), // 180 degree
                clockwise: true)
        
        path.addLine(to: CGPoint(x: viewWidth - viewWidth, y: (viewHeight - viewHeight) + viewHeight + 10))
        path.addLine(to: CGPoint(x: viewWidth - viewWidth, y: (viewHeight - viewHeight) + 10))
        
        path.addArc(withCenter: CGPoint(x: (viewWidth - viewWidth) + 10, y: (viewHeight - viewHeight) + 10),
                    radius: 10,
                    startAngle: CGFloat(Double.pi), // 180 degree
                endAngle: CGFloat(Double.pi / 2 ), // 90 degree
                clockwise: true)
        
        path.close()
        fillColor.setFill()
        path.fill()
    }
}

向我展示需要更改的示例或解释我在哪里做错了?

【问题讨论】:

    标签: swift drawing uibezierpath curve


    【解决方案1】:

    我使用“addCurve”而不是“addQuadCurve”解决了这个问题。 我要替换的代码

    来自:

    // center left edge
            
            path.addQuadCurve(to: CGPoint(x: (viewWidth / 2 ) - 35, y: (11/2.0)), controlPoint: CGPoint(x: (viewWidth / 2 ) - 35, y: 0))
            // end left edge
            
            path.addArc(withCenter: CGPoint(x: viewWidth / 2, y: 0), radius: 35, startAngle: CGFloat(Double.pi), endAngle: CGFloat(Double.pi * Double.pi), clockwise: false)
            
            // How to draw this curve?
            
            // center right edge
    //        path.addQuadCurve(to: CGPoint(x: (viewWidth / 2 ) + 35 + 10 , y: 0), controlPoint: CGPoint(x: (viewWidth / 2 ) + 35 - 10, y: 10))
            
            
            // end right edge
    

    到:

    // 中心左边缘

        path.addCurve(to: CGPoint(x: (viewWidth / 2) - 35.9, y: 10), controlPoint1: CGPoint(x: (viewWidth / 2) - 35, y: 0), controlPoint2: CGPoint(x: (viewWidth / 2) - 35, y: 10))
        // end left edge
        
        path.addArc(withCenter: CGPoint(x: viewWidth / 2, y: 0), radius: 36.5, startAngle: CGFloat(Double.pi), endAngle: CGFloat(2 * Double.pi), clockwise: false)
        
        // How to draw this curve?
        
        // center right edge
        path.addCurve(to: CGPoint(x: (viewWidth / 2) + 35 + 8, y: 0), controlPoint1: CGPoint(x: (viewWidth / 2) + 36, y: 10), controlPoint2: CGPoint(x: (viewWidth / 2) + 35, y: 0))
    
        // end right edge
    

    结果:

    【讨论】:

    • 看起来不太对劲。如果您仔细观察形状顶部中心的“缩进”,会发现有几个细尖刺。这可能是您的弧一直到 y=0 的结果。您应该将圆弧的 Y 位置降低 10 个点,使 y=10。 (您希望弧的起点和终点与两条曲线的终点相匹配。)
    • addCurve()addQuadCurve() 之间的区别非常微妙。 addQuadCurve() 添加具有一个中间控制点的二次贝塞尔曲线,addCurve() 添加具有两个中间控制点的三次贝塞尔曲线。都从当前点开始,到指定的结束点结束。
    • 感谢您的帮助,我将 Y 位置更改为 10,将圆半径更改为 36.5,并且所有尖峰都被删除了 :)
    【解决方案2】:

    在方格纸上画出你想做什么。绘制所有正在使用的直线、四边形曲线和圆弧段。

    我想你会发现你的弧线一直延伸到你的形状的顶部,覆盖你想要的圆角。您需要降低圆弧的 Y 位置,使圆弧的起点和终点从内圆角的末端开始,这些圆角略低于形状的顶部。

    【讨论】:

    • 你说得对!我解决了问题,几分钟后我将发布我的代码,如果你知道如何更优雅地解决这个问题,请告诉我。
    猜你喜欢
    • 1970-01-01
    • 2011-09-20
    • 1970-01-01
    • 1970-01-01
    • 2023-02-26
    • 1970-01-01
    • 1970-01-01
    • 2023-03-03
    • 2021-02-13
    相关资源
    最近更新 更多