SwiftUI 字体在复杂视图中缩放

wk.*_*tal 10 ios swift swiftui

我的目标是确保容器中的文本根据其父级进行缩放。当容器只包含一个 Text 视图时,它工作得很好,如下所示:

import SwiftUI

struct FontScalingExperiment: View {
    var body: some View {
        Text("Hello World ~!")
            .font(.system(size: 500))
            .minimumScaleFactor(0.01)
            .lineLimit(1)
            .padding()
            .background(
                RoundedRectangle(cornerRadius: 20)
                    .fill(Color.yellow)
                    .scaledToFill()  
        )
    }
}

struct FontScalingExperiment_Previews: PreviewProvider {
    static var previews: some View {
        Group {
            FontScalingExperiment()
                .previewLayout(.fixed(width: 100, height: 100))
            FontScalingExperiment()
                .previewLayout(.fixed(width: 200, height: 200))
            FontScalingExperiment()
                .previewLayout(.fixed(width: 300, height: 300))
            FontScalingExperiment()
                .previewLayout(.fixed(width: 400, height: 400))
        }

    }
}
Run Code Online (Sandbox Code Playgroud)

结果:

结果

但是,当我们有更复杂的 View 时,我们不能使用相同的方法根据其父级大小自动缩放文本,例如:

import SwiftUI

struct IndicatorExperiment: View {
    var body: some View {
        VStack {
            HStack {
                Text("Line 1")
                Spacer()
            }
            Spacer()
            VStack {
                Text("Line 2")
                Text("Line 3")
            }
            Spacer()
            Text("Line 4")
        }
        .padding()
        .background(
            RoundedRectangle(cornerRadius: 20)
                .fill(Color.yellow)
        )
            .aspectRatio(1, contentMode: .fit)
    }
}

struct IndicatorExperiment_Previews: PreviewProvider {
    static var previews: some View {
        Group {
            IndicatorExperiment()
                .previewLayout(.fixed(width: 100, height: 100))
            IndicatorExperiment()
                .previewLayout(.fixed(width: 200, height: 200))
            IndicatorExperiment()
                .previewLayout(.fixed(width: 300, height: 300))
            IndicatorExperiment()
                .previewLayout(.fixed(width: 400, height: 400))
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

只需添加这 3 个修饰符:

.font(.system(size: 500)) .minimumScaleFactor(0.01) .lineLimit(1)

不会像第一个例子那样产生结果;超出框架的文本被放大。我成功了,通过使用 GeometryReader 产生了我想要的结果,然后基于geometry.size.width. 这是在 SwiftUI 中实现预期结果的唯一方法吗?

Lor*_*lor 2

使用GeometryReader.minimumScaleFactor修饰符可能是缩放视图中文本的唯一方法。.frame为了更好地控制大小,一种可能的方法是从父视图提供大小。

可缩放文本视图

    GeometryReader { geo in
        Text("Foo")
            .font(
                .system(size: min(geo.size.height, geo.size.width) * 0.95))
            .minimumScaleFactor(0.05)
            .lineLimit(1)
    }
Run Code Online (Sandbox Code Playgroud)

使用可缩放文本视图的父视图

    GeometryReader { geo in
        ScaleableText()
            .frame(width: geo.size.width, height: geo.size.height)
    }
Run Code Online (Sandbox Code Playgroud)