我正在学习SwiftUI.我遇到了"GeometryReader".我想知道为什么以及何时使用它?

推荐答案

使现代化

101


GeometryReader是一个视图,通过它可以访问其父对象的大小和位置.例如:

struct MyView: View {
    var body: some View {
        GeometryReader { geometry in
           // Here goes your view content,
           // and you can use the geometry variable
           // which contains geometry.size of the parent
           // You also have function to get the bounds
           // of the parent: geometry.frame(in: .global)
        }
    }
}

我通常把它和.background()以获取其他视图的边界.例如,文本视图很难预先预测它的大小.当我需要这些信息时,我会使用以下技巧:

首先,我定义了一个称为GeometryGetter的视图:

struct GeometryGetter: View {
    @Binding var rect: CGRect
    
    var body: some View {
        return GeometryReader { geometry in
            self.makeView(geometry: geometry)
        }
    }
    
    func makeView(geometry: GeometryProxy) -> some View {
        DispatchQueue.main.async {
            self.rect = geometry.frame(in: .global)
        }

        return Rectangle().fill(Color.clear)
    }
}

然后,要获取文本视图(或任何其他视图)的边界:

struct MyView: View {
    @State private var rect: CGRect = CGRect()

    var body: some View {
        Text("some text").background(GeometryGetter($rect))

        // You can then use rect in other places of your view:
        Rectangle().frame(width: 100, height: rect.height)
    }
}

对于一些用例,我发布了一些使用GeometryReader的其他问题的答案.看看他们:

移动文本字段以避免被键盘隐藏:https://stackoverflow.com/a/56721268/7786555

如何在SwiftUI中将视图设置为另一个视图的大小:

Note

在GeometryGetter中,我添加了一个DispatchQueue.主要的async{}来设置rect.在某些情况下,它可能会导致运行时警告:Modifying state during view update.

Swift相关问答推荐

在swift静态var扩展中,如何或可以访问和返回具体类?

像WebSocket一样接收实时更新,但通过异步/等待或组合

Swift计时器未触发

CardStack 和 Lottie

如何在 swift 5.0 中获取当前行

为 ObservedObject 和 State 对象配置预览

有没有更快的方法来循环浏览 macOS 上已安装的应用程序?

如何在 Combine 合并运算符的输出上使用 eraseToAnyPublisher

Swift:创建用于调用 C 函数的指针数组

引用类型(类)不需要但 struct 需要的可识别 id

在 Swift 4 中实现自定义解码器

Swift 覆盖实例变量

调整文本的字体大小以适应 UIButton

try 在解除分配时加载视图控制器的视图... UIAlertController

playground 导入:没有这样的模块Foo

使用 swift IOS 使 UIBarButtonItem 消失

键盘显示时Tableview滚动内容

为什么枚举具有计算(computed)属性但在 Swift 中没有存储属性?

从 Swift 初始化程序调用方法

swift中相同的数据类型多变量声明