SwiftUI中的Geometry Reader是什么?

时间:2019-06-24 03:49:14

标签: swift swiftui

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

4 个答案:

答案 0 :(得分:16)

更新

自从我发布答案以来,我还写了一篇有关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)
    }
}

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

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中使另一个视图的大小: https://stackoverflow.com/a/56661706/7786555

注意

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

答案 1 :(得分:1)

在SwiftUI中什么叫Reader

除了kontiki的答案外,Reader是容器视图,将它们的内容定义为一个函数。因此,他们可以对自己的parent拥有某些访问权限和能力。如果您仔细观察,它们是通用结构,SwiftUI 2.0中现在有2个阅读器:

请注意,这只是一个约定,它们并没有符合View协议的更多特殊协议。

GeometryReader

struct GeometryReader<Content: View> : View

这是一个容器视图,根据其自身大小和坐标空间定义其内容。因此,您可以检测GeometryReader中任何帧和位置的变化以及任何视图的当前状态。该阅读器的一种流行用法是,当您需要在单独的堆栈中使用单独的视图时,它们具有相同(或相对)的大小。


ScrollViewReader

struct ScrollViewReader<Content: View> : View

该视图的子项是根据ScrollViewProxy的功能而定义的,该子项针对该子项中的可滚动视图。因此,您可以访问滚动视图,例如 scrolling to a specific item in a list 或类似的东西。

为尽量减少重复,我没有发布示例,如果需要,您可以查看链接以获取更多信息

答案 2 :(得分:0)

Kontiki的回答确实很有帮助,但对于只希望能够尽可能简单地使用几何读取器的人来说,也不必要地复杂。

您可以轻松地为视图提取几何读取器的值,并将其传递到代码中的其他任何位置:

struct ViewContainer: View {
var body: some View {
    GeometryReader { geometry -> YourView in
            extractedGeometryVariable = geometry.frame(in: .global)
            return YourView()
        }
    }
}

答案 3 :(得分:0)

GeometryReader是识别父视图几何图形的东西,这意味着当您在几何图形中创建视图时,您将获得父视图的大小。