swift - 我们如何在 SwiftUI 中使用 GeometryReader 获取和读取文本的大小?

标签 swift swiftui

我正在尝试根据文本字体的大小读取文本的宽度,正如我们所知,GeometryReader 将所有可能的给定位置交给他,在此代码中,它只采用给定的帧大小,我通过了它,但它没有取我文本的大小!我在做什么错?我什么 GeometryReader 开始只读取我的文本大小!不是自己的框架宽度。
enter image description here
这是我的代码:

struct ContentView: View {
    @State var fontSize: CGFloat = 20.0

    var body: some View {
        Spacer()

        textWidthGeometryReader(fontSize: $fontSize)

        Spacer()

        Text("Font size:" + "\(fontSize)")

        Slider(value: $fontSize, in: 20...40, step: 1)
            .padding()

        Spacer()
    }
}

struct textWidthGeometryReader: View {
    @Binding var fontSize: CGFloat

    var body: some View {
        GeometryReader { inSideGeometry in

            Text("width of Text:" + String(format: "%.0f", inSideGeometry.size.width))
                .font(.system(size: fontSize))
                .background(Color.yellow)
                .position(x: inSideGeometry.size.width / 2, y: inSideGeometry.size.height / 2)
        }
        .frame(width: 400, height: 300, alignment: .center)
        .background(Color.gray)
        .cornerRadius(20)
    }
}

最佳答案

您可以使用查看首选项。

  • 先创建一个自定义PreferenceKey对于 View 大小:
  • struct ViewSizeKey: PreferenceKey {
        static var defaultValue: CGSize = .zero
    
        static func reduce(value: inout CGSize, nextValue: () -> CGSize) {
            value = nextValue()
        }
    }
    
  • 创建一个将计算其大小并将其分配给 ViewSizeKey 的 View :
  • struct ViewGeometry: View {
        var body: some View {
            GeometryReader { geometry in
                Color.clear
                    .preference(key: ViewSizeKey.self, value: geometry.size)
            }
        }
    }
    
  • 在您的 View 中使用它们:
  • struct ContentView: View {
        @State var fontSize: CGFloat = 20.0
        @State var textSize: CGSize = .zero
    
        var body: some View {
            Spacer()
            Text("width of Text:" + String(format: "%.0f", textSize.width))
                .font(.system(size: fontSize))
                .background(ViewGeometry())
                .onPreferenceChange(ViewSizeKey.self) {
                    textSize = $0
                }
            Spacer()
            Text("Font size:" + "\(fontSize)")
            Slider(value: $fontSize, in: 20...40, step: 1)
                .padding()
            Spacer()
        }
    }
    

    查看首选项是一个相当高级的主题。你可以在这里找到更详细的解释:
  • The magic of view preferences in SwiftUI
  • Inspecting the View Tree – Part 1: PreferenceKey
  • 关于swift - 我们如何在 SwiftUI 中使用 GeometryReader 获取和读取文本的大小?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64452647/

    相关文章:

    SwiftUI:可重用跨平台(iOS 和 macOS) View 中的导航栏标题

    animation - 有没有更好的方法在 swiftui 中实现摇动动画?

    swift - NSSetUncaughtExceptionHandler 在 Swift 3 中没有触发?

    ios - UILabel 文本使用 NSTimer 更新,但在触摸/拖动 UITableView 时不更新(gif 示例)

    c - Swift:访问作为对象的 C 结构成员

    SwiftUI:类型不符合协议(protocol) 'UIViewRepresentable'

    ios - ScrollView 内的 ForEach 不占用整个宽度

    SwiftUI页面控件实现

    ios - Swift:延迟 UITableViewCell 选择

    ios - 为什么我在 Swift 的 UITableView 中看不到任何单元格?