微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

iOS 如何使用贝塞尔曲线实现我的绘图?

如何解决iOS 如何使用贝塞尔曲线实现我的绘图?

我的 collectionView 部分需要有边框和圆角半径。所以如果它是第一行,我需要绘制一个无底矩形层。如果是最后一行,我会画一个裸照层。

如何使用贝塞尔曲线实现我的绘图?

enter image description here

已编辑

我用过这个代码,它有效。但我无法为裸上身矩形创建方法

extension CGMutablePath {
 static func bottomlessRoundedRect(in rect: CGRect,radius: CGFloat) -> CGMutablePath {
    let path = CGMutablePath()
    path.move(to: CGPoint(x: rect.minX,y: rect.maxY))
    path.addArc(tangent1End: CGPoint(x: rect.minX,y: rect.minY),tangent2End: CGPoint(x: rect.maxX,radius: radius)
    path.addArc(tangent1End: CGPoint(x: rect.maxX,y: rect.maxY),radius: radius)
    path.addLine(to: CGPoint(x: rect.maxX,y: rect.maxY))
    return path
 }
}

let layer = CAShapeLayer()
layer.linewidth = 1
layer.strokeColor = UIColor.black.cgColor
layer.fillColor = nil
layer.path = CGMutablePath.bottomlessRoundedRect(in: testView.bounds.insetBy(dx: 1,dy: 1),radius: 18)
view.layer.insertSublayer(layer,at: 0)

view.layoutIfNeeded()

这里是无上装矩形的方法,它不能正常工作。

static func toplessRoundedRect(in rect: CGRect,y: rect.minY))
    path.addArc(tangent1End: CGPoint(x: rect.minX,tangent2End: CGPoint(x: rect.minX,radius: radius)

    path.addArc(tangent1End: CGPoint(x: rect.minX,y: rect.minY))
    return path
}

这是结果。

enter image description here

请帮助我拥有正确的裸照。 (之前没用过画图)

答案

static func toplessRoundedRect(in rect: CGRect,radius: radius)

    path.addArc(tangent1End: CGPoint(x: rect.maxX,y: rect.minY))
    return path
}

解决方法

画出来。圆角矩形是一系列连接到给定半径的四分之一圆弧的线段。 (拐角半径。)

iOS 根据您的绘图方式使用不同的坐标系(Core Graphics 使用 LLO,或左下原点,而 UIKit/Core Animation 使用 ULO,或左上原点。)

看起来 CAShapeLayers 中使用的 CGPaths 使用 ULO(左上角原点)坐标,其中 0,0 位于左上角,Y 随向下而增加。

您的bottomlessRoundedRect() 函数以这行代码开头:

path.move(to: CGPoint(x: rect.minX,y: rect.maxY))

移动到矩形的左下方(最大 Y)位置开始。

注释整个函数,这是它的作用:

static func bottomlessRoundedRect(in rect: CGRect,radius: CGFloat) -> CGMutablePath {
    let path = CGMutablePath()
    //Move to the lower left corner of the rect (starting point)
    path.move(to: CGPoint(x: rect.minX,y: rect.maxY))
    
    //Draw a line from the starting point to the beginning of the arc in the
    //top left corner,and draw the top left rounded corner
    path.addArc(tangent1End: CGPoint(x: rect.minX,y: rect.minY),tangent2End: CGPoint(x: rect.maxX,radius: radius)
    
    //Draw a line from the top left corner to the begnning of the top right
    //arc,and the top right corner arc
    path.addArc(tangent1End: CGPoint(x: rect.maxX,y: rect.maxY),radius: radius)
    
    //Draw a final line from the end of the top right corner arc to
    //the bottom right corner
    path.addLine(to: CGPoint(x: rect.maxX,y: rect.maxY))
    return path
}

绘制完整的矩形。选择您的拐角半径。绘制一个内部矩形,其角由角半径插入。在内部矩形的角处画圆,并注意它们如何与外部矩形的边相交。

现在把它放在一起。

打开一条贝塞尔曲线。移动到您想要的起点。创建一条到下一边的线,减去您的拐角半径。以完成该角所需的角度开始和结束绘制 1/4 圆弧。绘制下一条线段。再画一条弧线。绘制最后的线段。

toplessRoundedRect() 函数的注释版本如下所示:

static func toplessRoundedRect(in rect: CGRect,radius: CGFloat) -> CGMutablePath {
    let path = CGMutablePath()
    
    //Move to the top left corner.
    path.move(to: CGPoint(x: rect.minX,y: rect.minY))
    
    //Draw a line from the top left corner to the begnning of the bottom left
    //rounded corner,plus the bottom left rounded corner
    path.addArc(tangent1End: CGPoint(x: rect.minX,radius: radius)
    
    //Draw a line from the end of the bottom left rounded corner to the beginning
    //of the bottom right rounded corner,plus the bottom right rounded corner
    path.addArc(tangent1End: CGPoint(x: rect.maxX,radius: radius)
    
    //Draw a line from the end of the bottom right rounded corner
    //to the top right corner.
    path.addLine(to: CGPoint(x: rect.maxX,y: rect.minY))
    return path
}
,

这里有一个提示:一次一行地完成你的代码。

将您的 CGMutablePath 扩展名更改为:

extension CGMutablePath {
    static func bottomlessRoundedRect(in rect: CGRect,radius: CGFloat) -> CGMutablePath {
        let path = CGMutablePath()
        // 1
        path.move(to: CGPoint(x: rect.minX,y: rect.maxY))
        // 2
        //path.addArc(tangent1End: CGPoint(x: rect.minX,radius: radius)
        // 3
        //path.addArc(tangent1End: CGPoint(x: rect.maxX,radius: radius)
        // 4
        //path.addLine(to: CGPoint(x: rect.maxX,y: rect.maxY))
        return path
    }
}

当您运行应用时,只会执行路径的 1 部分。您什么也看不到,因为到目前为止您所做的只是 move 到一点。

现在,取消对 2 部分的注释。运行你的代码,看看结果是什么。

取消注释 3 部分。运行你的代码,看看结果是什么。

取消注释 4 部分。运行你的代码,看看结果是什么。

现在,您应该非常清楚代码的作用,创建您的 toplessRoundedRect func 应该是小菜一碟。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。