SwiftUI 文本 scaledToFit 和换行文本

SwiftUI Text scaledToFit and wrap text

我有一个带有动态文本的按钮。我希望缩小文本以适应它(尽可能多),并将文本换行到一定数量的行(可能是 2 行?)。

默认情况下,SwiftUI 似乎将文本换行。但似乎当我在 Text 视图上使用 scaledToFit 修饰符时,它会阻止单词换行。

这里有一些 playground 代码来说明:

import SwiftUI
import PlaygroundSupport

struct ContentView: View {
  var body: some View {

    let lorem = "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum."

    VStack {

      // Here is the default text - see in the screenshot that it properly wraps the text
      HStack {
        Text(lorem)
      }
      .frame(width: 100, height: 100)
      .background(Color.blue)

      // Here is text that is scaled down, but prevented from wrapping, even though 
      // we have allowed it to use 2 lines.
      HStack {
        Text(lorem)
          .allowsTightening(true)
          .scaledToFit()
          .lineLimit(2)
          .minimumScaleFactor(0.7)
      }
      .frame(width: 100, height: 100)
      .background(Color.green)

      // Here is the text with the same scaling modifiers as above, but it
      // is still set to the original font size
      HStack {
        Text("Short")
          .allowsTightening(true)
          .scaledToFit()
          .lineLimit(2)
          .minimumScaleFactor(0.7)
      }
      .frame(width: 100, height: 100)
      .background(Color.pink)

    }
  }
}

PlaygroundPage.current.setLiveView(ContentView())

因此,理想情况下,我想要第一个和第二个视图的组合 - 我希望文本换行,但如果文本不能立即适合父视图,我也希望缩小到某个最小尺寸。

试试这个,粉红色也类似:

    HStack {
        Text(lorem)
            .frame(width: 100, height: 100)  // <--- here
            .allowsTightening(true)
            .lineLimit(2)
            .scaledToFit()
            .minimumScaleFactor(0.7)
    }
    .frame(width: 100, height: 100)
    .background(Color.green)