问题是如何在父视图中获得实际呈现的大小和位置?换句话说,如何在下面的Text("Foo")
代码中获得实际的SwiftUI大小?
GeometryReader
可用于通过safeAreaInsets
获取父size
和安全区嵌入,这些信息在GeometryProxy
中定义。您可以从下面的屏幕截图中看到,建议的VStack
大小是300
宽度和300
高度,VStack
的实际大小未知。
struct FooView: View {
var body: some View {
GeometryReader { geometryProxy in
VStack {
Text("\(geometryProxy.size.height), \(geometryProxy.size.width)")
Text("Foo")
}
.background(Color.green)
}
.frame(width: 300, height: 300)
.background(Color.blue)
}
}
发布于 2020-08-15 05:17:32
实际呈现大小
解决方法是通过带有嵌套.background
的GeometryReader
修饰符获得实际呈现的大小。然后,可以将新几何代理中的大小信息存储在视图中定义的临时@State
变量中。
struct FooSizePreferenceKey: PreferenceKey {
static let defaultValue = CGSize.zero
static func reduce(value: inout CGSize, nextValue: () -> CGSize) {
value = nextValue()
}
}
struct FooView: View {
@State private var fooSize: CGSize = .zero
var body: some View {
GeometryReader { geometryProxy in
VStack {
Text("\(self.fooSize.height), \(self.fooSize.width)")
Text("Foo")
.background(
GeometryReader { fooProxy in
Color
.green
.preference(key: FooSizePreferenceKey.self,
value: fooProxy.size)
.onPreferenceChange(FooSizePreferenceKey.self) { size in
self.fooSize = size
}
}
)
}
}
.frame(width: 300, height: 300)
.background(Color.blue)
}
}
实际渲染位置
可以使用Anchor
和anchorPreference
计算视图的实际呈现位置。使用锚点和父geometryProxy
,可以很容易地获得目标视图的位置.bound
信息。
struct FooAnchorData: Equatable {
var anchor: Anchor<CGRect>? = nil
static func == (lhs: FooAnchorData, rhs: FooAnchorData) -> Bool {
return false
}
}
struct FooAnchorPreferenceKey: PreferenceKey {
static let defaultValue = FooAnchorData()
static func reduce(value: inout FooAnchorData, nextValue: () -> FooAnchorData) {
value.anchor = nextValue().anchor ?? value.anchor
}
}
struct FooView: View {
@State private var foo: CGPoint = .zero
var body: some View {
GeometryReader { geometryProxy in
VStack {
Text("\(self.foo.x), \(self.foo.y)")
Text("Foo")
.background(
GeometryReader { fooProxy in
Color
.green
.anchorPreference(key: FooAnchorPreferenceKey.self,
value: .bounds,
transform: {FooAnchorData(anchor: $0) })
.onPreferenceChange(FooAnchorPreferenceKey.self) { data in
self.foo = geometryProxy[data.anchor!].origin
}
}
)
}
}
.frame(width: 300, height: 300)
.background(Color.blue)
}
}
https://stackoverflow.com/questions/63422759
复制相似问题