繁体   English   中英

在 SwiftUI 中使用 GeometryReader 定位视图

[英]Positioning Views with GeometryReader in SwiftUI

我在滚动视图中有一组子视图(GridView1 和 GridView2)。 子视图在一个 VStack 中,因为我需要它们一个一个地放在另一个下面。 我有一个 GeometryReader 包装子视图,每个子视图内部都有一个 GeometryReader。 我需要子视图中的 GeometryReader 来确定我在 LazyVGrid 中需要的列间距的宽度。

问题是,在子视图中使用 GeometryReader 会导致两个子视图堆叠在一起。 我试图设置子视图的框架大小,但这限制了垂直滚动并且没有给我正确的结果。

对于解决此问题的任何帮助,我将不胜感激。

内容视图:

struct ContentView: View {
    var body: some View {
        GeometryReader { geo in
            ScrollView {
                VStack(spacing: 20) {
                    GridView1()
                    GridView2()
                }//.frame(minHeight: 0, maxHeight: .infinity)
            }
        }
        .padding()
    }
}

网格视图 1:

struct GridView1: View {
    var body: some View {
        GeometryReader { g in
            let maxwidth = g.size.width/6 > 100 ? g.size.width/6 : 100
            let columns = Array(repeating: GridItem(.flexible(minimum: 100, maximum: maxwidth), spacing: 0), count: 6)
            
            ScrollView(.horizontal) {
                LazyVGrid(columns: columns, alignment: .leading, spacing: 10, pinnedViews: [.sectionHeaders]) {
                    Section(header: Text("Grid 1").font(.title)) {
                        ForEach(0...200, id:\.self) { index in
                            Text("\(index)").frame(maxWidth: .infinity)
                        }
                    }
                }
            }
            .background(Color.blue)
        }
    }
}

GridView2(GridView1 和 GridView2 本质上是一样的东西)

struct GridView2: View {
    var body: some View {
        GeometryReader { g in
            let maxwidth = g.size.width/10 > 100 ? g.size.width/10 : 100
            let columns = Array(repeating: GridItem(.flexible(minimum: 100, maximum: maxwidth), spacing: 0), count: 10)
            ScrollView(.horizontal) {
                LazyVGrid(columns: columns, alignment: .leading, spacing: 20, pinnedViews: [.sectionHeaders]) {
                    Section(header: Text("Grid 2").font(.title)) {
                        ForEach(1000...1200, id:\.self) { index in
                            ZStack {
                                Text("\(index)")
                            }
                            .frame(maxWidth: .infinity)
                            .background(Color.green)
                        }
                    }//.frame(minHeight: 0, maxHeight: .infinity)
                }
            }//.frame(minHeight: 1000, maxHeight: .infinity)
            //.frame(maxWidth: .infinity, maxHeight: .infinity)
            //.background(Color.red)
        }
    }
}

这是我所期待的:

在此处输入图像描述

在此处输入图像描述

这是我目前得到的。 正如您在下面看到的,子视图聚集在顶部。

在此处输入图像描述

不要使用混淆外部ScrollView的内部GeometryReader ,而是将宽度从顶部GeometryReader传递到子视图网格中。

这是可行的解决方案。 使用 Xcode 12.1 / iOS 14.1 测试

演示

struct ContentView: View {
    var body: some View {
        GeometryReader { geo in
            ScrollView {
                VStack(spacing: 20) {
                    GridView1(width: geo.size.width)
                    GridView2(width: geo.size.width)
                }
            }
        }
        .padding()
    }
}

struct GridView1: View {
    let width: CGFloat
    var body: some View {
        let maxwidth = width/6 > 100 ? width/6 : 100
        let columns = Array(repeating: GridItem(.flexible(minimum: 100, maximum: maxwidth), spacing: 0), count: 6)
        
        ScrollView(.horizontal) {
            LazyVGrid(columns: columns, alignment: .leading, spacing: 10, pinnedViews: [.sectionHeaders]) {
                Section(header: Text("Grid 1").font(.title)) {
                    ForEach(0...200, id:\.self) { index in
                        Text("\(index)").frame(maxWidth: .infinity)
                    }
                }
            }
        }
        .background(Color.blue)
    }
}

struct GridView2: View {
    let width: CGFloat
    var body: some View {
        let maxwidth = width/10 > 100 ? width/10 : 100
        let columns = Array(repeating: GridItem(.flexible(minimum: 100, maximum: maxwidth), spacing: 0), count: 10)
        ScrollView(.horizontal) {
            LazyVGrid(columns: columns, alignment: .leading, spacing: 20, pinnedViews: [.sectionHeaders]) {
                Section(header: Text("Grid 2").font(.title)) {
                    ForEach(1000...1200, id:\.self) { index in
                        ZStack {
                            Text("\(index)")
                        }
                        .frame(maxWidth: .infinity)
                        .background(Color.green)
                    }
                }
            }
        }
    }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM