您可以在 SwiftUI 中以编程方式显式设置滚动视图的内容偏移量吗?

时间:2021-06-25 14:07:18

标签: swiftui swiftui-scrollview

是否可以在 UI 的不同级别共享两个滚动视图的内容偏移量?甚至可以在 SwiftUI 中控制滚动视图的内容偏移量吗?我知道 ScrollView 现在可以滚动到特定项目,如果该项目有一个 id,但如果用户与其中一个交互,我希望两个滚动视图一起滚动。我不能为两个部分使用一个滚动的原因是我试图完成一个网格,其中左列和第一行都是粘性的。下面是完成这个网格的代码:

struct ContentView: View {
    let rows = Array(repeating: GridItem.init(.fixed(44), spacing: 0), count: 8)
    @State private var scrollViewContentOffset: CGFloat = 0

    var body: some View {
        NavigationView {
            ScrollView {
                LazyVStack(spacing: 0, pinnedViews: [.sectionHeaders]) {
                    Section(header: gridView()) {
                        HStack(spacing: 0) {
                            firstColumnHeaderView()
                                .frame(width: 95)
                            TrackableScrollView([.horizontal], showsIndicators: false, contentOffset: $scrollViewContentOffset) {
                                LazyHGrid(rows: rows, spacing: 0) {
                                    ForEach(0...55, id: \.self) { index in
                                        GridCell(title: "Index \(index)")
                                            .background(index % 2 == 0 ? Color.purple : Color.orange)
                                    }
                                }
                            }
                        }
                    }
                }
            }
            .navigationTitle(Text("Sticky Grid"))
            .navigationBarTitleDisplayMode(.inline)
        }
    }
    
    private func gridView() -> some View {
        LazyVStack(spacing: 0, pinnedViews: [.sectionHeaders]) {
            Section(header: firstRowHeaderView()) {
                // Content here goes below the first sticky header/row
            }
        }
    }
    
    private func firstRowHeaderView() -> some View {
        let rowItems = [
            HeaderItem(title: "Price"),
            HeaderItem(title: "Change"),
            HeaderItem(title: "Ask"),
            HeaderItem(title: "Bid"),
            HeaderItem(title: "Quantity"),
            HeaderItem(title: "Last"),
            HeaderItem(title: "Close"),
            HeaderItem(title: "Today")
        ]
        
        return HStack(spacing: 0) {
            GridCell(title: "Symbol")
            TrackableScrollView([.horizontal], showsIndicators: false, contentOffset: $scrollViewContentOffset) {                LazyHStack(spacing: 0) {
                    ForEach(rowItems, id: \.id) { item in
                        GridCell(title: item.title)
                    }
                }
            }
        }
        .background(Color.white)
    }
    
    private func firstColumnHeaderView() -> some View {
        let columnItems = [
            HeaderItem(title: "AAPL"),
            HeaderItem(title: "MS"),
            HeaderItem(title: "E"),
            HeaderItem(title: "TPPY"),
            HeaderItem(title: "MSFT"),
            HeaderItem(title: "A"),
            HeaderItem(title: "IBM"),
            HeaderItem(title: "TSLA")
        ]
        
        return LazyVStack(alignment: .leading, spacing: 0) {
            ForEach(columnItems, id: \.id) { item in
                GridCell(title: item.title)
                    .background(Color.white)
            }
        }
    }
}

struct HeaderItem {
    let id = UUID()
    let title: String
}

struct GridCell: View {
    let title: String
    
    var body: some View {
        VStack(spacing: 0) {
            Spacer()
            Text("\(title)")
            Spacer()
            Divider()
                .background(Color.black)
        }
        .frame(width: 95, height: 44)
    }
}

Pinned first row Pinned first column Two scrolled horizontal scroll views

当视图垂直滚动时,顶行被固定,第一列也被固定。但是您可以看到标题的顶行(在符号之后)应该水平滚动,而事实并非如此。其下方的网格项也是如此,但它们是两个不同的滚动视图。它们是否可以通过某种绑定一起滚动?

0 个答案:

没有答案
相关问题