我正在学习SwiftUI。我遇到了“ GeometryReader”。我想知道为什么以及何时使用它?
答案 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)
Reader
?除了kontiki的答案外,Reader
是容器视图,将它们的内容定义为一个函数。因此,他们可以对自己的parent
拥有某些访问权限和能力。如果您仔细观察,它们是通用结构,SwiftUI 2.0中现在有2个阅读器:
请注意,这只是一个约定,它们并没有符合View
协议的更多特殊协议。
struct GeometryReader<Content: View> : View
这是一个容器视图,根据其自身大小和坐标空间定义其内容。因此,您可以检测GeometryReader
中任何帧和位置的变化以及任何视图的当前状态。该阅读器的一种流行用法是,当您需要在单独的堆栈中使用单独的视图时,它们具有相同(或相对)的大小。
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是识别父视图几何图形的东西,这意味着当您在几何图形中创建视图时,您将获得父视图的大小。