SwiftUI 中的 GeometryReader
GeometryReader 是 SwiftUI 中的一个重要布局容器,它允许你访问父视图提供的可用大小和坐标空间信息。
基本用法
swift
GeometryReader { geometry in
// 在这里可以使用 geometry 参数访问布局信息
Text("宽度: \(geometry.size.width)")
}
GeometryProxy 属性
GeometryReader 的闭包参数是一个 GeometryProxy
对象,它包含以下属性:
size: CGSize
- 父视图提供的可用空间大小safeAreaInsets: EdgeInsets
- 安全区域边距frame(in: CoordinateSpace) -> CGRect
- 获取视图在不同坐标空间中的框架
实际应用示例
1. 获取视图尺寸
swift
GeometryReader { geometry in
Rectangle()
.fill(Color.blue)
.frame(width: geometry.size.width * 0.5,
height: geometry.size.height * 0.3)
}
2. 响应式布局
swift
GeometryReader { proxy in
if proxy.size.width > 500 {
// 宽屏布局
HStack {
ContentView()
SidebarView()
}
} else {
// 窄屏布局
VStack {
ContentView()
SidebarView()
}
}
}
3. 获取全局位置
swift
GeometryReader { geometry in
Circle()
.fill(Color.red)
.frame(width: 50, height: 50)
.onAppear {
let frame = geometry.frame(in: .global)
print("圆在屏幕上的位置: \(frame.origin)")
}
}
注意事项
-
布局行为 :GeometryReader 会尽可能占用所有可用空间,类似于
Color.clear
或Spacer()
-
性能考虑:过度使用 GeometryReader 可能会影响性能,特别是在滚动视图中
-
无限尺寸问题:在某些容器(如 List 或 ScrollView)中,GeometryReader 可能会接收到不合理的无限尺寸
-
坐标空间 :可以使用
.coordinateSpace(name:)
修饰符创建自定义坐标空间
高级用法
自定义坐标空间
swift
VStack {
Text("Header")
.coordinateSpace(name: "header")
GeometryReader { geometry in
let frame = geometry.frame(in: .named("header"))
Text("相对于Header的位置: \(frame.minY)")
}
}
与其他视图结合
swift
struct SizeReportingView: View {
@Binding var size: CGSize
var body: some View {
GeometryReader { geometry in
Color.clear
.preference(key: SizePreferenceKey.self, value: geometry.size)
.onAppear { size = geometry.size }
}
}
}
GeometryReader 是 SwiftUI 中实现复杂布局和响应式设计的强大工具,合理使用可以创建出更加灵活的用户界面。