【问题标题】:List style SwiftUI列表样式 SwiftUI
【发布时间】:2021-05-09 18:10:24
【问题描述】:

如何做一个像图中这样的列表? (编辑:列表标题)

这是我尝试过的 - 列表和表单:

NavigationView {
    VStack {
        List { // or Form here
            // Text("New") <- this also isn't it
            Section(header: Text("New")) {
                ForEach(... ... .indices, id: \.self) { index in
                    ...
                    ...
                }
            }
            
            Section(header: Text("Done")) {
                ForEach(...) { ...
                    ...
                }
            }
     }
}
            // On the pictures below - `List` on the left; `Form` on the right

【问题讨论】:

  • 也许你知道如何将它从灰色和全字母一个高度变成像照片上的标题样式?
  • 我不认为这些标题是章节标题。这看起来像两个单独的列表,标题完全分开

标签: listview swiftui swiftui-list swiftui-form


【解决方案1】:

它看起来像一个带有部分的表单,可以配置部分标题(如下所示),行内容根据需要组成

NavigationView {
    Form {
        Section(header: Text("New").bold().font(.title).foregroundColor(.black)) {

编辑:.textCase(.none) 允许源文本大写“Xxxx”

Section(header: Text("New").bold().font(.title).textCase(.none).foregroundColor(.black))

【讨论】:

  • 谢谢!都是一个高度。我正在寻找如何做“新”,而不是“新”。
  • 这就是有效的方法:Section(header: Text("New").bold().font(.title).textCase(.none).foregroundColor(.black)) ...... .textCase(.none) 解决了大写问题。
【解决方案2】:

这是一个使用滚动视图、自定义部分和自定义列表项的解决方案。每个部分都有自己的标题、颜色和总数。每个项目都有一个图标、标签和切换。切换按钮在部分总计中添加或删除项目的价格。

[]

struct CustomListSectionView: View {
    @ObservedObject var listSection : CustomListSection

    var body: some View {
        VStack(spacing: 0) {
            headerView
                .padding(8)
            listView
                .padding()
                .background(RoundedRectangle(cornerRadius: 25.0).foregroundColor(.white))
                .padding(.horizontal)
            footerView
                .padding(8)
        }
        .background(Color.secondary)
    }
    
    var headerView : some View {
        HStack {
            Text(listSection.header)
                .font(.system(size: 24, weight: .medium, design: .rounded))
                .foregroundColor(.primary)
            Spacer()
        }
    }
    
    var listView : some View {
        VStack(spacing: 3) {
            ForEach(Array(listSection.items.enumerated()), id: \.offset) { index, item in
                CustomListItemView(color: listSection.color).environmentObject(item)
                if index < listSection.items.count - 1 {
                    Divider()
                }
            }
        }
    }

    var footerView : some View {
        HStack {
            Spacer()
            Text("Sum:")
                .font(.system(size: 18, weight: .semibold, design: .rounded))
                .foregroundColor(.secondary)
            Text(CustomListSectionView.formatter().string(from: NSNumber(value: listSection.total)) ?? "-")
                .font(.system(size: 18, weight: .medium, design: .rounded).monospacedDigit())
                .foregroundColor(.primary)
        }
    }
    
    static func formatter() -> NumberFormatter {
        let currencyFormatter = NumberFormatter()
        currencyFormatter.locale = Locale.current
        currencyFormatter.numberStyle = .currency
        currencyFormatter.usesGroupingSeparator = true
        return currencyFormatter
    }
}

struct CustomListItemView: View {
    @EnvironmentObject var listItem : CustomListItem
    let color : Color
    
    var body: some View {
        HStack {
            ZStack {
                Image(systemName: listItem.symbol)
                    .font(.headline)
                    .foregroundColor(.white.opacity(0.8))
                    .padding(6)
                    .background(Circle().foregroundColor(color))
            }
            .shadow(radius: 3)
            Text(listItem.name)
            Spacer()
            Button(action: { listItem.select.toggle() }) {
                Image(systemName: listItem.select ? "largecircle.fill.circle" : "circle")
                    .foregroundColor(.accentColor)
                    .padding(6)
            }.buttonStyle(PlainButtonStyle())
        }
    }
}

class CustomListSection: ObservableObject, Hashable {
    // hashable so id: \.self work in ForEach's
    let id = UUID()
    let header : String
    let color : Color
    @Published var items : [CustomListItem] = []
    @Published var total : Double = 0
    
    func add(_ name: String, _ symbol: String, _ amount: Double) {
        items.append(CustomListItem(name, symbol, amount, calc))
    }
    
    func calc() {
        total = items.map({ $0.price }).reduce(0, +)
    }
    
    init(_ header: String, _ color: Color) {
        self.header = header
        self.color = color
    }
    
    public func hash(into hasher: inout Hasher) {
            hasher.combine(id)
    }
    
    static func == (lhs: CustomListSection, rhs: CustomListSection) -> Bool {
        lhs.id == rhs.id
    }
}

class CustomListItem: ObservableObject, Hashable {
    @Published var select : Bool = false { didSet {
        withAnimation { calc() }
    } }
    let name : String
    let symbol : String
    @Published var amount : Double
    let calc : () -> Void

    init(_ name: String, _ symbol: String, _ amount: Double, _ calc: @escaping () -> Void) {
        self.name = name
        self.symbol = symbol
        self.amount = amount
        self.calc = calc
    }

    var price : Double { select ? amount : 0 }
    
    // hashable so id: \.self work in ForEach's
    let id = UUID()

    public func hash(into hasher: inout Hasher) {
            hasher.combine(id)
    }
    
    static func == (lhs: CustomListItem, rhs: CustomListItem) -> Bool {
        lhs.id == rhs.id
    }
}

struct CustomListSectionView_Previews: PreviewProvider {
    static var previews: some View {
        let section = CustomListSection("Section Name", .purple)
        section.add("Alpha Item", "a.circle", 1000)
        section.add("Delta Item", "d.circle", 100)
        section.add("Omega Item", "z.circle", 1)
        return CustomListSectionView(listSection: section)
    }
}

【讨论】:

    猜你喜欢
    • 2020-05-15
    • 2019-10-27
    • 2023-02-10
    • 1970-01-01
    • 2018-03-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-04-18
    相关资源
    最近更新 更多