ScrollView内部的GeometryReader会折叠GeometryReader,无论子项大小如何

时间:2020-07-07 11:36:59

标签: swiftui

我正在尝试制作一个子视图,其中包含一个绘图,我希望其尺寸与父容器的一部分成比例。

这很好,除了将其放在层次结构中某个位置的滚动视图中之外。

从屏幕快照中可以看到,堆栈中的声音最大,符合预期。但是,当您将内容放置在滚动视图中时,几何图形读取器的大小会缩小到接近零,并且其子级会超出其边界。好像它在不同的Z索引上渲染其子级。实际上,如果从几何渲染内容中删除包装的VStack,它实际上并不会像包装在ZStack中一样布置其所有子对象。

编辑: 需要明确的是:ScrollView不属于该组件。该组件不应该知道它是否在ScrollView中-它只是一个可怜的无助组件,被扔掉了。这就是为什么我将ScrollView放入预览代码而不是组件的原因。

我尝试了各种固定大小,人与事,理想的组合。我唯一能找到的解决方法是hacky solution-问题底部的编辑部分,其中几何读取器报告的宽度通过解决方法捕获到状态变量中,然后重新用于设置框架同级视图的大小。

注意,我是一个完整的初学者。滚动视图和几何读取器之间似乎存在一些交互作用,这超出了我目前的理解。

似乎是confusing topic

import SwiftUI

struct ScrollViewGeoReader: View {
    var body: some View {
        GeometryReader{ g in
            VStack{
                let width = g.size.width
                Circle().frame(width: width/3, height: width/3, alignment: .center)
                Text("inside geo")
                Text("inside geo")
                Text("inside geo \(width)")
                Text("inside geo")
                Text("inside geo")
            }
            .border(Color.green, width: 2)
        }
        .border(Color.red, width: 3)
    }
}

struct ScrollViewGeoReader_Previews: PreviewProvider {
    static var previews: some View {
        VStack {
//            VStack {
            ScrollView {
                ScrollViewGeoReader()
                Text("Next scrollview item")
            }
            .border(Color.blue, width: 2)

        }
    }
}

ZStack(预期布局):

ZStack (expected layout)

ScrollView(查看几何图形的红色框如何折叠到大小10):

enter image description here

编辑:

还要注意,有或没有圆圈都会出现相同的问题,这也是我遇到的问题。因此,就宽度捕获而言,这至少不是鸡肉/鸡蛋,至少就圆圈而言。我希望Text组件知道它们自己的大小,并告诉GR。

enter image description here

vs

enter image description here

1 个答案:

答案 0 :(得分:0)

这里是布局不可行的解决方案(不包括子视图分离)。如果/当内部子视图分开时,可以通过构造函数参数注入几何宽度。

使用Xcode 12测试。

demo

struct TestScrollViewWithGeometry: View {
    var body: some View {
        GeometryReader{ g in
            ScrollView {
                VStack{
                    let width = g.size.width
                    Circle().frame(width: width/3, height: width/3, alignment: .center)
                    Text("inside geo")
                    Text("inside geo")
                    Text("inside geo \(width)")
                    Text("inside geo")
                    Text("inside geo")
                }
                .border(Color.green, width: 2)
                Text("Next scrollview item")
            }
            .border(Color.blue, width: 2)
        }
        .border(Color.red, width: 3)
    }
}