首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何在SwiftUI中获得呈现的实际视图大小和位置?

如何在SwiftUI中获得呈现的实际视图大小和位置?
EN

Stack Overflow用户
提问于 2020-08-15 05:02:38
回答 1查看 1.6K关注 0票数 4

问题是如何在父视图中获得实际呈现的大小和位置?换句话说,如何在下面的Text("Foo")代码中获得实际的SwiftUI大小?

GeometryReader可用于通过safeAreaInsets获取父size和安全区嵌入,这些信息在GeometryProxy中定义。您可以从下面的屏幕截图中看到,建议的VStack大小是300宽度和300高度,VStack的实际大小未知。

代码语言:javascript
运行
复制
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)
    }
}
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-08-15 05:17:32

实际呈现大小

解决方法是通过带有嵌套.backgroundGeometryReader修饰符获得实际呈现的大小。然后,可以将新几何代理中的大小信息存储在视图中定义的临时@State变量中。

代码语言:javascript
运行
复制
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)
    }
}

实际渲染位置

可以使用AnchoranchorPreference计算视图的实际呈现位置。使用锚点和父geometryProxy,可以很容易地获得目标视图的位置.bound信息。

代码语言:javascript
运行
复制
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)
    }
}

票数 6
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/63422759

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档