如何创建可适应其子级不断变化的大小的ScrollView

时间:2019-07-19 21:35:49

标签: ios swiftui

[测试版4]我有一张卡片列表,当用户点击它们以显示更多信息时,每张卡片都可以展开。

但是,当卡的大小更改时,包含的ScrollView不会展开或收缩。

我发现完成这项工作的唯一方法是使用列表-它似乎会自动调整内容,但这不是我想要的,因为它引入了列表的其他功能(最明显的是分隔符)。 / p>

不使用ForEach(即仅堆叠几个Card()会产生相同的结果。

在Beta 3中,我找到了一种解决方法,将expanded设为@Binding,然后为每张卡设置一个@State数组,但是从Beta 4开始,此方法不再起作用因为变化的值不会再向上传播,除非我在父视图中也有一个直接绑定到此数组的元素(即,还有一个切换)。似乎@State的状态仅在实际上有直接绑定到它的元素时才更改。

struct ExpandableChildViewTest: View {

    var body: some View {

        ScrollView {
            VStack(alignment: .leading, spacing: 20) {
                ForEach(1...10) { _ in
                    Card()
                }
            }
        }
        .padding()
            .border(Color.green, width: 1)
    }
}

struct Card: View {

    @State private var expanded = true

    var body: some View {

        ZStack {
            Rectangle()
                .frame(height: expanded ? 350: 100)
                .foregroundColor(Color.blue)
                .cornerRadius(20)
                .padding(.vertical)
                .tapAction() {
                    self.expanded.toggle()
            }
        }
    }
}


我希望(希望)包含的Scrollview在其子级更改大小时调整其大小,但这不会发生。这会导致内容从Scrollview中掉出来,或者在Scrollview中有很多额外的空间。

The picture shows the extra white space at the top because the second card is collapsed. The outer Scrollview does not recompute itself.

1 个答案:

答案 0 :(得分:0)

(我的名声尚未允许发表评论,所以我正在使用这种方式...) 我有一个类似的情况:时间轴具有不同的粒度(十年,年份,月份等),用户可以平滑缩放,而比例尺也可以相应地采用。到目前为止,我发现的唯一方法是为当前放大倍数计算比例尺的整体宽度,并将其移交给模型。然后,嵌入的视图将获得一个具有该宽度的.frame,然后ScrollView会正确处理滚动。

但是,这远非优雅。由于嵌入式视图实际上知道其宽度,因此应该以某种方式(但如何?)使ScrollView知道该宽度。在我的环境中,ScrollView(没有显式.frame)仅显示一个空白屏幕,显式.frame一切正常(但性能不足)。

顺便说一句:从Beta 5开始,绑定的方式发生了变化。现在,您使用@ObservedObject var model: Model在视图中设置模型,并使用@Published var something: SomeType传播模型的更改,这比以前容易得多。