在SwiftUI中在形状内换行多行文字

在SwiftUI中在形状内换行多行文字,swiftui,word-wrap,shapes,Swiftui,Word Wrap,Shapes,正如标题所述,我正在寻找一种在SwiftUI中将多行文本包装到形状中的方法(请参见下图)。我尝试使用.clipToShape(MyShape()),但这只会使形状中不存在的任何文本不可见 我在过去使用UIKit和排除路径实现了这一点,但我想找到一种方法来实现与SwiftUI相同的效果 如有任何建议,将不胜感激 我找到了一种数字方法,但它可能不是最好的方法 它应该可以在IOS和macOS上运行。我用swiftUI在macOS上测试了它 我们要做的第一件事是找出有多少个字体大小高的矩形与直径圆相匹配

正如标题所述,我正在寻找一种在SwiftUI中将多行文本包装到形状中的方法(请参见下图)。我尝试使用.clipToShape(MyShape()),但这只会使形状中不存在的任何文本不可见

我在过去使用UIKit和排除路径实现了这一点,但我想找到一种方法来实现与SwiftUI相同的效果

如有任何建议,将不胜感激


我找到了一种数字方法,但它可能不是最好的方法

它应该可以在IOS和macOS上运行。我用swiftUI在macOS上测试了它

我们要做的第一件事是找出有多少个字体大小高的矩形与直径圆相匹配。然后我们计算出它们的宽度。最后一步是为每个矩形获取适合的字符数量,并将它们添加到数组中。通过将孔阵列转换回字符串,我们在每个矩形后添加一个“\n”,以获得正确的多行对齐

func createCircularText(text: String, verticalSpacing: Double,  circleDiameter: Double, FontSize: Double) -> String {
    
    var Text = text
    
    var circularText = String()
 
    var CountOfWordLines = Int()
   
    var widthOfWordLine = [Int]()
    
    var widthOfWordLineSorted = [Int]()
    
    var array = [String]()
    
    let heigthOfWordLines = FontSize + verticalSpacing

    
    var Dnum = (((1/heigthOfWordLines) * circleDiameter) - 2.0)
    Dnum.round(.up)
    CountOfWordLines = Int(Dnum)
    
    
    for n in 1...(CountOfWordLines / 2) {

        
                let num0 = circleDiameter / 2.0
                let num1 = pow(num0, 2.0)
                let num2 = (Double(n) * heigthOfWordLines)
                let num3 = pow(num2,2.0)
                let num4 = num1 - num3
                let num5 = sqrt(Double(num4))
                let num = Int((num5 / 10) * 3)
                widthOfWordLine.append(Int(num))
        
    }
    
    widthOfWordLineSorted.append(contentsOf: widthOfWordLine.sorted { $1 > $0 })
    widthOfWordLine.removeFirst()
    widthOfWordLineSorted.append(contentsOf: widthOfWordLine)
    widthOfWordLine.removeAll()
    
    for n in widthOfWordLineSorted {
        
        
        array.append(String(Text.prefix(n)))

       if Text.isEmpty {} else {
        let t = Text.dropFirst(n)
        Text = String(t)
        }
    }
    
    
    circularText = array.joined(separator: "\n")
    

    return circularText 
}
在我们看来,我们嵌入了如下函数:

@State var text = "your text"
@State var CircularText = String()


// body:

    ZStack {
                    
        Circle().frame(width: 200)
        
         Text(CircularText)
         .multilineTextAlignment(.center)

            }

.onAppear(perform: {
CircularText = createCircularText(text: text, verticalSpacing: 3.0, circleDiameter: 200, FontSize: 12)
 })
我刚刚测试了它的字体大小12,但它应该执行任何其他以及相当不错

通过更改直径,您会注意到文本变得有点椭圆形,要修复此问题,请更改垂直间距。数字越小,圆圈越高,反之亦然。但请随意解决这个问题

另外,请确保您的文本足够长