这种布局可以用 SwiftUI 实现吗?

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

我一直在尝试使用 SwiftUI 构建以下布局。

最初我用

Grid
构建了大部分内容,嵌入到
ScrollView
中。然后我想我可以在底部添加列表部分,但是列表不能用 SwiftUI 嵌入到 ScrollViews 中,这与 UIKit 不同,如果你愿意,你可以在
UITableView
中嵌入
UIScrollView

然后我尝试删除

ScrollView
,并使用具有多个部分的
List
,在第一部分中使用
Grid
,但这也不起作用。

我基本上必须使用

LazyVStack
构建自定义列表吗? 我不需要 List 的任何内置功能,例如选择或行操作。

感谢您花时间阅读我的帖子。

swiftui gridview swiftui-list
1个回答
0
投票

我已经用LazyVStack实现了您的上述要求。您可以检查我的下面的代码并进行相应的更改。您也可以在其上添加按钮或操作。

import SwiftUI


var screenWidth: Double {
    return UIScreen.main.bounds.size.width
}

var screenHeight: Double {
    return UIScreen.main.bounds.size.height
}

struct NoSeparatorListV<Content>: View where Content: View {
    let content: () -> Content

    init(@ViewBuilder content: @escaping () -> Content) {
        self.content = content
    }

    var body: some View {
        if #available(iOS 14.0, *) {
            ScrollView {
                LazyVStack(spacing: 0) {
                    self.content()
                }
            }
        } else {
            List {
                self.content()
            }
            .onAppear {
                UITableView.appearance().separatorStyle = .none
            }.onDisappear {
                UITableView.appearance().separatorStyle = .singleLine
            }
        }
    }
}

class LabelInfo {
    var labelName: String
    var labelValue: String
    var labelID: String
    init(labelName: String, labelValue: String, labelID: String) {
        self.labelName = labelName
        self.labelValue = labelValue
        self.labelID = labelID
    }
}
var label1 = LabelInfo(labelName: "Label1", labelValue: "Value1", labelID: "1")
var label2 = LabelInfo(labelName: "Label2", labelValue: "Value2", labelID: "2")
var label3 = LabelInfo(labelName: "Label3", labelValue: "Value3", labelID: "3")
var labelInfoV: [LabelInfo] = [label1, label2, label3]
var labelInfoH1: [LabelInfo] = [label1, label2]
var labelInfoH2: [LabelInfo] = [label1, label2, label3]
struct StackOverFlow: View {
    var body: some View {
        ZStack {
            Color.gray
            NoSeparatorListV {
                Image(systemName: "person")
                    .resizable()
                    .background(Color.red)
                    .frame(height: screenHeight * 0.30) // assuming height of image is 40% of any scree size
                    .cornerRadius(10)
                    .padding([.trailing,.leading,.top], 12)
                ForEach(labelInfoV, id: \.labelID) { label in
                    HStack {
                        VStack(alignment: .leading, content: {
                            Text(label.labelName)
                            Text(label.labelValue)
                        })
                        .padding([.leading,.trailing], 8)
                        Spacer()
                    }
                    .background(Color.red)
                    .cornerRadius(10)
                    .padding([.trailing,.leading,.top], 12)
                }
                HStack {
                    // width of them should equal to (screenWidth - (trailing + leading + allOtherGapsPaddingValues))
                    VStack(alignment: .leading, content: {
                        Text("Label4")
                        Text("Value4")
                    })
                    .frame(width: (screenWidth - 32)/2)
                    .background(Color.red)
                    .cornerRadius(10)
                    .padding([.leading], 8)

                    VStack(alignment: .leading, content: {
                        Text("Label4")
                        Text("Value4")
                    })
                    .frame(width: (screenWidth - 32)/2)
                    .background(Color.red)
                    .cornerRadius(10)
                    .padding([.trailing], 8)
                }
                .padding([.trailing,.leading,.top], 12)

                HStack {
                    // width of them should equal to (screenWidth - (trailing + leading + allOtherGapsPaddingValues))
                    VStack(alignment: .leading, content: {
                        Text("Label5")
                        Text("Value5")
                    })
                    .frame(width: (screenWidth - 48)/3)
                    .background(Color.red)
                    .cornerRadius(10)
                    .padding([.leading], 8)

                    VStack(alignment: .leading, content: {
                        Text("Label6")
                        Text("Value6")
                    })
                    .frame(width: (screenWidth - 48)/3)
                    .background(Color.red)
                    .cornerRadius(10)
                    .padding([.trailing], 8)

                    VStack(alignment: .leading, content: {
                        Text("Label7")
                        Text("Value7")
                    })
                    .frame(width: (screenWidth - 48)/3)
                    .background(Color.red)
                    .cornerRadius(10)
                    .padding([.trailing], 8)
                }
                .padding([.trailing,.leading,.top], 12)

                NoSeparatorListV {
                    ForEach(1..<10) { i in
                        VStack {
                            HStack {
                                Text("Title: \(i)")
                                    .background(Color.red)
                                    .cornerRadius(10)
                                Spacer()
                                Text("Details")
                            }
                            .padding([.top], 4)
                            .padding([.trailing], 8)
                            Rectangle()
                                .frame(height: 0.5)
                                .background(Color.green)
                                .opacity(i%2 == 1 ? 0.3 : 0.7)
                        }
                        .padding([.leading], 8)
                    }
                }
                .background(Color.red)
                .cornerRadius(10)
                .padding([.trailing,.leading,.top], 12)
            }
        }
        .padding([.bottom,.top],12)
    }
}


#Preview {
    StackOverFlow()
}

注意:您可以使用 LazyHStack 对这些水平标签使用 forEach 循环。

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