【问题标题】:Wrapping multiline text inside a shape in SwiftUI在 SwiftUI 中将多行文本包装在形状内
【发布时间】:2021-04-17 10:18:35
【问题描述】:

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

我过去曾使用 UIKit 和排除路径完成此操作,但想找到一种方法来使用 SwiftUI 实现相同的效果。

任何建议将不胜感激。

【问题讨论】:

    标签: swiftui word-wrap shapes


    【解决方案1】:

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

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

    我们要做的第一件事是找出有多少具有字体大小高度的矩形适合其直径的圆。然后我们计算出它们的宽度。最后一步是为每个矩形获取适合的字符数量并将它们添加到数组中。通过将孔数组转换回字符串,我们在每个矩形后添加一个“\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 号字体测试了它,但它应该与任何其他字体一样好。

    通过更改直径,您会注意到文本变得有点椭圆,要解决这个问题,请更改verticalSpacing。数字越小,圆圈越大,反之亦然。但请随时解决该问题。

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-09-08
      • 2021-07-30
      • 1970-01-01
      • 2020-03-28
      • 2019-09-22
      • 2023-03-08
      • 1970-01-01
      相关资源
      最近更新 更多