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.