首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >忽略SwiftUI ScrollView VStack GeometryReader高度

忽略SwiftUI ScrollView VStack GeometryReader高度
EN

Stack Overflow用户
提问于 2020-10-10 12:29:58
回答 1查看 2.6K关注 0票数 3

我希望在ScrollView之外使用VStack,这样如果VStack扩展到屏幕大小之外,内容就可以滚动。现在,我想在GeometryReader中使用VStack,它会导致问题,我只能通过设置GeometryReader框架来解决问题,这并不能真正帮助我,因为我使用读取器来定义视图大小。

下面是没有ScrollView的代码,它运行得很好:

代码语言:javascript
复制
struct MyExampleView: View {
  var body: some View {
    VStack {
        Text("Top Label")
            .background(Color.red)
        
        GeometryReader { reader in
            Text("Custom Sized Label")
                .frame(width: reader.size.width, height: reader.size.width * 0.5)
                .background(Color.green)
        }
        
        Text("Bottom Label")
            .background(Color.blue)
    }
    .background(Color.yellow)
  }
}

这将产生以下图像:

自定义大小的标签应该是全宽度,但高度应该是宽度的一半。现在,如果我将相同的代码包装在ScrollView中,就会发生这样的情况:

不仅仅是所有的东西都变小了,而且定制标签的高度也被忽略了。如果我设置了GeometryReader的高度,我可以调整它的行为,但是我希望GeometryReader能够和它的内容一样大。我怎样才能做到这一点?

谢谢

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-10-10 13:02:44

应该理解,GeometryReader不是一个神奇的工具,它只是读取当前上下文父级中的可用空间,但是.ScrollView没有自己的可用空间,它是零,因为它从内部内容确定需要的空间.因此,在这里使用GeometryReader,您有循环子请求父母的大小,但父母期望大小从子.SwiftUI渲染器以某种方式解决了这个问题(找到最小的已知大小),只是为了不崩溃。

以下是您的场景的可能解决方案--这里的适当工具是视图首选项。用Xcode 12 / iOS 14编写和测试。

代码语言:javascript
复制
struct DemoLayout_Previews: PreviewProvider {
    static var previews: some View {
        Group {
          MyExampleView()
          ScrollView { MyExampleView() }
        }
    }
}

struct MyExampleView: View {
    @State private var height = CGFloat.zero
    var body: some View {
        VStack {
            Text("Top Label")
                .background(Color.red)
            
            Text("Custom Sized Label")
                .frame(maxWidth: .infinity)
                .background(GeometryReader {
                    // store half of current width (which is screen-wide)
                    // in preference
                    Color.clear
                        .preference(key: ViewHeightKey.self, 
                            value: $0.frame(in: .local).size.width / 2.0)
                })
                .onPreferenceChange(ViewHeightKey.self) {
                    // read value from preference in state
                    self.height = $0
                }
                .frame(height: height) // apply from stored state
                .background(Color.green)
            
            Text("Bottom Label")
                .background(Color.blue)
        }
        .background(Color.yellow)
    }
}

struct ViewHeightKey: PreferenceKey {
    typealias Value = CGFloat
    static var defaultValue = CGFloat.zero
    static func reduce(value: inout Value, nextValue: () -> Value) {
        value += nextValue()
    }
}

注:.如果您不确定视图所在的上下文,请不要使用GeometryReader。

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

https://stackoverflow.com/questions/64293429

复制
相关文章

相似问题

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