如何在 ForEach 视图中的每个项目之间添加分隔线?

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

我正在尝试构建一个循环遍历对象数组的 ForEach。一切工作正常,但我不知道如何在元素之间添加分隔符。

行的布局位于单独的视图中,我尝试向行添加一个分隔符,这导致列表末尾看起来很糟糕,因为分隔符位于最后一项下方。

我无法使用List,因为它不是页面上的唯一视图。一切都在 ScrollView 中。

作为参考,这里是到目前为止的代码和 UI。

这是列表视图的代码:

VStack {
        ForEach (manufacturers) { manufacturer in
          NavigationLink(destination: Text("test")) {
            Row(manufacturer: manufacturer)
          }
        }
      }
      .background(Color("ListBackground"))
      .cornerRadius(12)

这是行视图的代码:

VStack {
      HStack {
        Text(manufacturer.name)
          .font(.system(size: 18, weight: .regular))
          .foregroundColor(.black)
        Spacer()
        Image(systemName: "chevron.right")
          .foregroundColor(.secondary)
      }
    }
    .padding()
    .buttonStyle(PlainButtonStyle())

有没有办法在 ForEach 循环中在每个项目之间添加分隔符,或者我可以从最后一个项目中删除分隔符

我对能得到的每一个帮助感到高兴。

ios swift listview swiftui foreach
3个回答
19
投票

这是一种可能的方法

    ForEach (manufacturers) { manufacturer in
      VStack {
        NavigationLink(destination: Text("test")) {
          Row(manufacturer: manufacturer)
        }

        // I don't known your manufacturer type so below condition might
        // require fix during when you adapt it, but idea should be clear
        if manufacturer.id != manufacturers.last?.id {
           Divider()
        }
      }
    }

3
投票

您可以删除具有比较计数的最后一行。

struct Row: View {
    var manufacturer: String
    var isLast: Bool = false
    var body: some View {
        VStack {
            HStack {
                Text(manufacturer)
                    .font(.system(size: 18, weight: .regular))
                    .foregroundColor(.black)
                Spacer()
                Image(systemName: "chevron.right")
                    .foregroundColor(.secondary)
            }
            if !isLast {
                Divider()
            }
        }
        .padding()
        .buttonStyle(PlainButtonStyle())
    }
}

struct ContentView5: View {
    private var manufacturers = ["1", "2", "3"]
    
    var body: some View {
        VStack {
            ForEach (manufacturers.indices, id: \.self) { idx in
                NavigationLink(destination: Text("test")) {
                    Row(manufacturer: manufacturers[idx], isLast: idx == manufacturers.count - 1)
                }
            }
        }
        .background(Color("ListBackground"))
        .cornerRadius(12)
    }
}

或者您可以从行中删除最后一个变量。

 VStack {
    ForEach (manufacturers.indices, id: \.self) { idx in
        NavigationLink(destination: Text("test")) {
            Row(manufacturer: manufacturers[idx])
        }
        if idx != manufacturers.count - 1 {
            Divider()
        }
    }
}

3
投票

您可以使用通用的“DividedForEachView,它会在除最后一个元素之外的每个元素之后插入分隔符。

struct DividedForEach<Data: RandomAccessCollection, ID: Hashable, Content: View, D: View>: View {
    let data: Data
    let id: KeyPath<Data.Element, ID>
    let content: (Data.Element) -> Content
    let divider: (() -> D)

    init(_ data: Data, id: KeyPath<Data.Element, ID>, content: @escaping (Data.Element) -> Content, divider: @escaping () -> D) {
       self.data = data
       self.id = id
       self.content = content
       self.divider = divider
    }

    var body: some View {
        ForEach(data, id: id) { element in
            content(element)
        
            if element[keyPath: id] != data.last![keyPath: id] {
                divider()
            }
        }
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.