SwiftUI:对轴上的嵌套滚动视图

问题描述 投票:0回答:1

我正在尝试创建一个在顶层具有垂直滚动视图的界面,然后创建一个水平滚动视图(使用 iOS 17 中新的分页滚动)来显示用户可以在其之间横向滚动的多个子视图。到目前为止,它的行为完全符合我的要求,除了水平滚动视图中第一个视图的高度似乎设置了其他每个视图的高度,即使它们具有更高的内容。老实说,我不确定我想象中的行为是什么,但我想知道是否有人解决了类似的问题或以另一种方式设计了类似的布局。

这是一个最小的可重现示例:

import SwiftUI

struct ContentView: View {
    @State private var selectedTab: String? = "Tab 1"

    var body: some View {
        ScrollView(.vertical) {
            LazyVStack {
                Image(systemName: "photo.fill")
                    .resizable()
                    .aspectRatio(contentMode: .fill)

                ScrollView(.horizontal) {
                    LazyHStack(spacing: 0) {
                        SampleView(.purple, 5)
                            .id("Tab 1")
                            .containerRelativeFrame(.horizontal)

                        SampleView(.red, 12)
                            .id("Tab 2")
                            .containerRelativeFrame(.horizontal)

                        SampleView(.blue, 20)
                            .id("Tab 3")
                            .containerRelativeFrame(.horizontal)
                    }
                    .scrollTargetLayout()
                }
                .scrollPosition(id: $selectedTab)
                .scrollTargetBehavior(.paging)
            }
        }
    }

    @ViewBuilder
    func SampleView(_ color: Color, _ size: Int) -> some View {
        LazyVGrid(columns: Array(repeating: GridItem(), count: 2), content: {
            ForEach(1...size, id: \.self) { _ in
                RoundedRectangle(cornerRadius: 15)
                    .fill(color.gradient)
                    .frame(height: 150)
            }
        })
    }
}

从示例中可以看到,水平滚动视图的高度被锁定在第一个子视图的高度。

ios swift swiftui uiscrollview
1个回答
0
投票

发生这种情况是因为

LazyHStack
用于水平滚动内容。外部
LazyVStack
的高度基于
LazyHStack
的初始高度,并且使用第一个子视图的高度,因为其他子视图不可见,因此尚未调整大小。

如果将

LazyHStack
更改为
HStack
,则垂直滚动将达到最高孩子的完整高度。当然,您也可以向下滚动到第一个孩子之外。您可能还想添加
.top
对齐:

ScrollView(.vertical) {
    LazyVStack {
        Image(systemName: "photo.fill")
            // ...

        ScrollView(.horizontal) {
            HStack(alignment: .top, spacing: 0) { // 👈 HERE
                // ...
            }
            .scrollTargetLayout()
        }
        .scrollPosition(id: $selectedTab)
        .scrollTargetBehavior(.paging)
    }
}

Animation

© www.soinside.com 2019 - 2024. All rights reserved.