SwiftUI 中的几何 Reader 是什么?

What is Geometry Reader in SwiftUI?

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

更新

既然贴出了答案,我也写了一篇关于GeometryReader如何工作的文章。查看更详细的解释:https://swiftui-lab.com/geometryreader-to-the-rescue/


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 的其他问题的答案。查看它们:

移动文本字段以避免被键盘隐藏:

如何在 SwiftUI 中使视图大小与另一个视图相同:

备注

在 GeometryGetter 中,我添加了一个 DispatchQueue.main.async {} 来设置矩形。在某些情况下,它可能会导致运行时警告,否则:在视图更新期间修改状态

SwiftUI 中的 Reader 是什么意思?

除了 kontiki 的答案之外,Readers 是将其内容定义为函数的容器视图。因此,他们可以获得一些关于他们 parent 的访问权限和能力。如果您仔细观察,它们是通用结构,现在 SwiftUI 2.0 中有 2 个 reader 可用:

请注意,这只是一个约定,它们不符合更多 View 协议.

的特殊协议

几何阅读器

struct GeometryReader<Content: View> : View

这是一个容器视图,将其内容定义为其自身大小和坐标的函数 space。因此,您可以在 GeometryReader 内检测框架和位置变化以及任何视图的当前状态。此 reader 的一种流行用法是,当您需要在单独的堆栈中使用具有相同(或相对)大小的单独视图时。


ScrollViewReader

struct ScrollViewReader<Content: View> : View

这是一个视图,其子项被定义为 ScrollViewProxy 的函数,目标是子项中的可滚动视图。所以你可以访问滚动视图,比如 或类似的东西。

为了尽量减少重复,我没有post示例,如果需要,您可以查看link了解更多信息

GeometryReader 可以识别父视图的几何图形,这意味着当您在几何图形中创建视图时,您会获得父视图的大小。