如何将线段之类的文本弯曲成带有核心图形的圆形?

问题描述

问题是针对 BezierPath 提出的,但现在我不必使用 bezier,它也可以使用核心图形。

我正在尝试绘制弯曲的文本(形状可以从直线到圆形开始),我看到 CoreText 允许我们在 UIBezierPath 路径上绘制文本。所以我试图画一条直线,并通过给定的弯曲系数值将其弯曲成圆形。如果值为零,它应该直线,如果它的正弯曲线向下侧弯曲,否则将线向上侧弯曲[文本将沿着这条路径绘制。]

有没有办法像这样将具有给定“弯曲系数”的直线弯曲成带有 UIBezierPath 的圆形?

enter image description here

我已经尝试过,实际上我不相信......用2个控制点绘制曲线,如果弯曲系数为0绘制直线其他曲线而曲线!=半圆然后用半圆更新路径以完成路径如果弯曲系数为正值,则变成一个圆圈,如果弯曲系数为负值,则进行反向操作,看起来直线会转换为圆形,但这不是一个方法。为了更好地理解,请看here>

例如:

    let r = textFXmodel.radius // This is bend factor
    
    if r != 0.0 { // If bend factor is equals to zero draw straight line

        let positiveR = abs(r)
        let fullSize = self.bounds.size
        var curvedLinePath = UIBezierPath()

        let insetRect = self.bounds.insetBy(dx: 10,dy: 10)
        let maximumValue = Float(insetRect.size.width / 2)
        let minimumValue = -Float(insetRect.size.width / 2)

        if r >= 0.0 { // If bend factor 'r' is positive value
            if r <= CGFloat(maximumValue / 2) { // If bend factor 'r' less then half of circle ⌢

                // Draw curved line and bend it from control points
                let controlPoint1 = CGPoint(x: fullSize.width / 2 - (r + r * 0.2),y: fullSize.height / 2 - (r * 1.5))
                let controlPoint2 = CGPoint(x: fullSize.width / 2 + (r + r * 0.2),y: fullSize.height / 2 - (r * 1.5))
                let curveStartPoint = CGPoint(x: r,y: fullSize.height / 2)
                let curveEndPoint = CGPoint(x: fullSize.width - r,y: fullSize.height / 2)
                curvedLinePath.move(to: curveStartPoint)
                curvedLinePath.addCurve(to: curveEndPoint,controlPoint1: controlPoint1,controlPoint2: controlPoint2)
                
            } else { // bend factor 'r' is greater or equal to half circle so remove curved line and draw half circle path

                let scaledRadius: CGFloat = r - 60
                let centerPoint = CGPoint(x: fullSize.width / 2,y: fullSize.height / 2)
                let startAngel = CGFloat.pi - (scaledRadius * 0.023)
                let endAngle = (CGFloat.pi * 2) + (scaledRadius * 0.023)
                curvedLinePath.removeAllPoints()
                curvedLinePath = UIBezierPath(arcCenter: centerPoint,radius: (fullSize.width / 4),startAngle: startAngel,endAngle: endAngle,clockwise: true)
            }
            
        } else {
            
            if r >= CGFloat(minimumValue / 2) {

                let controlPoint1 = CGPoint(x: fullSize.width / 2 - (positiveR + positiveR * 0.2),y: fullSize.height / 2 + (positiveR * 1.5))
                let controlPoint2 = CGPoint(x: fullSize.width / 2 + (positiveR + positiveR * 0.2),y: fullSize.height / 2 + (positiveR * 1.5))
                let curveStartPoint = CGPoint(x: positiveR,y: fullSize.height / 2)
                let curveEndPoint = CGPoint(x: fullSize.width - positiveR,controlPoint2: controlPoint2)
                
            } else {

                let scaledRadius: CGFloat = positiveR - 60
                let centerPoint = CGPoint(x: fullSize.width / 2,y: fullSize.height / 2)
                let startAngel = CGFloat.pi + (scaledRadius * 0.023)
                let endAngle = (CGFloat.pi * 2) - (scaledRadius * 0.023)
                curvedLinePath.removeAllPoints()
                curvedLinePath = UIBezierPath(arcCenter: centerPoint,clockwise: false)
            }
        }

      // and here goes drawing code...

我的代码有效 like this 它看起来像半路换行符 (:

如果您有一种不用 BezierpathCoreText 来绘制这样的文字方法,请与我分享。我在谷歌上搜索了很多,我阅读了关于这个主题的所有答案,但没有人帮助我,甚至 this answerthis

更新:- 在这个版本中,线段会在同一个中心弯曲,但这也不是真正的圆,它看起来像水滴形

private func updatePath(withRadius radius: CGFloat) -> UIBezierPath {
    var curveStartPoint: CGPoint = .zero
    var curveEndPoint: CGPoint = .zero
    var controlPoint1: CGPoint = .zero
    var controlPoint2: CGPoint = .zero
    if radius > 0.0 {
        controlPoint1 = CGPoint(x: size.width / 2 - (radius + radius * 0.2),y: size.height / 2 - radius)
        controlPoint2 = CGPoint(x: size.width / 2 + (radius + radius * 0.2),y: size.height / 2 - radius)
        curveStartPoint = CGPoint(x: radius,y: size.height / 2 + (radius * 0.5))
        curveEndPoint = CGPoint(x: size.width - radius,y: size.height / 2 + (radius * 0.5))
    } else {
        let positateR: CGFloat = abs(radius)
        controlPoint1 = CGPoint(x: size.width / 2 - (positateR + positateR * 0.2),y: size.height / 2 + positateR)
        controlPoint2 = CGPoint(x: size.width / 2 + (positateR + positateR * 0.2),y: size.height / 2 + positateR)
        curveStartPoint = CGPoint(x: positateR,y: size.height / 2 + (radius * 0.5))
        curveEndPoint = CGPoint(x: size.width - positateR,y: size.height / 2 + (radius * 0.5))
    }

    let drawingPath = UIBezierPath()
    drawingPath.move(to: curveStartPoint)
    drawingPath.addCurve(to: curveEndPoint,controlPoint2: controlPoint2)
    return drawingPath
}

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)