swiftui 列表视图布局问题

时间:2021-01-29 15:26:48

标签: list listview swiftui

我制作了一个“RowView”,并希望使用 swiftUI 显示列表中的每一行。

我希望每一行都像这样: enter image description here

因此我编写了代码。基于 GeometryReader,我想让行占据屏幕高度的 1/4,然后是全宽,带有填充和圆角。

我写的代码如下:

var body: some View {
    HStack {
        GeometryReader {g in
            ZStack {

                Image("Dummy")                      
                    .resizable()
                    .aspectRatio(contentMode: .fill)
                    .frame(width: g.size.width, height: g.size.height/4)
                    .frame(width: g.size.width)
                    .clipped(antialiased: true)
                    .cornerRadius(25)

                VStack {
                    HStack {
                        Spacer()
                        Image(systemName: "photo.on.rectangle.angled")
                            .resizable()
                            .aspectRatio(contentMode: .fit)
                            .frame(width:g.size.height/18, height: g.size.height/18)
                        Text("A Long Titlte here................")
                            .font(.title2)
                            .bold()
                            .minimumScaleFactor(0.1)
                        Spacer()
                    }.background(Color.red)
                }.frame(width: g.size.width, height: g.size.height/6)
                .frame(width: g.size.width, height: g.size.height/12)
                .background(Color.white)
                .opacity(0.7)
                .offset(y:g.size.height/18)
                
            }
        }.padding()
    }
}

在我创建了这个 RowView 之后,我创建了 ListView。

代码如下:

var body: some View {
    NavigationView {
        GeometryReader{ g in
        List {
            ForEach(modelData.rows) { row in
                RowView(property: row)
            }
        }.navigationBarTitle("ListView")
        }
    }
}

然而,行高没有达到预期,而是缩小了。

enter image description here

我不想“硬编码”行的高度。有什么方法可以根据我在 RowView 中设置的内容制作显示每个 RowView 的 ListView?

2 个答案:

答案 0 :(得分:0)

您有两个 GeometryReader(一个包裹另一个),它们有可能产生一些有趣的效果,特别是因为内部的 List 是一个 ScrollView,它也是一个 {{1} }.

仅使用外部(列表周围的)并将高度作为参数(或框架修饰符)传递给内部视图怎么样?

类似于:

var body: some View {
    NavigationView {
        GeometryReader{ g in
        List {
            ForEach(modelData.rows) { row in
                RowView(property: row)
                 .frame(height: g.size.height / 4)
            }
        }.navigationBarTitle("ListView")
        }
    }
}

然后,在您的行中,您的 frame 上现在连续有两个 VStack 修饰符。摆脱那里无关的东西。

答案 1 :(得分:0)

我也找到了解决方案。

GeometryReader 与可用的父容器的 heightwidth 一起使用。

所以你必须给父容器一个固定的高度。您可以使用屏幕尺寸来实现您想要的结果。

var body: some View {
    NavigationView {
        GeometryReader{ g in
            List {
                ForEach(modelData.rows) { row in
                    RowView(property: row)
                        .frame(height: UIScreen.main.bounds.size.height/4) // <--
                }
            }.navigationBarTitle("ListView")
        }
    }
}