Row List with More Items in SwiftUI

Usually, a row in a list displays one element, but there are cases when you need to show more items. Think about the list displayed in LinkedIn under the ‘Network’ section. What I want to build is something like that.

We have a card with a background, a photo, and some personal information.

We need to follow two steps:

  • Create the info card
  • Create the list

Create the info card

Let’s start by taking a look at the code:

struct PhotoCard: View {
    let imageName: String
    let title: String
    let subtitle: String
    var delete : () -> ()
    
    var body: some View {
        VStack {
            ZStack {
                VStack(spacing: 0) {
                    Color(.magenta)
                        .frame(width: .infinity, height: 50)
                    Color(.white)
                        .frame(width: .infinity, height: 50)
                }
                Image(imageName)
                  .resizable()
                  .foregroundColor(.blue)
                  .frame(width: 70, height: 70)
                  .clipShape( Circle())
            }.overlay (
                VStack {
                    HStack {
                        Spacer()
                        Button(action: delete) {
                            Image(systemName: "xmark.circle.fill")
                                .foregroundColor(.gray)
                        }
                    }.padding(5)
                    Spacer()
                }
            )
            Text(title)
                .font(.title2)
                .fontWeight(.bold)
                .frame(height: 30)
            Text(subtitle)
                .font(.subheadline)
                .foregroundColor(.secondary)
        }
        .background(Color.white)
        .cornerRadius(10)
        .shadow(radius: 5)
        .padding(1)
    }
}

The card receives the information to display, along with a callback function that is triggered when the user clicks the X button.

The card is a VStack with rounded corners—nothing special here. The interesting part is at the beginning, where we use a ZStack to display the colored background, half magenta and half white. On top of the background, we display the photo in a circular shape (automatically centered in the ZStack). The close button is displayed using the overlay and Its position is achieved by working with a combination of VStack, HStack, and Spacer.

Create the list

The code:

struct Person: Identifiable {
    let id = UUID()
    var name: String
    var title: String
    var image: String
}

struct ContentView: View {
    @State var items = [Person(name: "Geek", title: "Senior Geek", image: "image"),
                        Person(name: "Junior Geek", title: "Junior Geek", image: "junior"),
                        Person(name: "Nicola De Filippo", title: "Senior Geek", image: "image")]
    
    var body: some View {
        GeometryReader { geometry in
            NavigationView {
                ScrollView {
                    ForEach((0...items.count / 2), id: \.self) { index in
                        HStack {
                            Spacer()
                            if items.count > index * 2 {
                                PhotoCard(
                                    imageName: items[index * 2].image,
                                    title: items[index * 2].name,
                                    subtitle: items[index * 2].title, delete:
                                        {
                                            delete(index * 2)
                                        }
                                ).frame(width: geometry.size.width * 0.45)
                            }
                            if items.count > index * 2 + 1 {
                                PhotoCard(
                                    imageName: items[index * 2 + 1].image,
                                    title: items[index * 2 + 1].name,
                                    subtitle: items[index * 2 + 1].title,
                                    delete:
                                        {
                                            delete(index * 2 + 1)
                                        }
                                ).frame(width: geometry.size.width * 0.45)
                            } else {
                                Divider()
                                    .frame(width: geometry.size.width * 0.45, height: 0)
                            }
                            Spacer()
                        }
                    }
                    
                }.listStyle(PlainListStyle())
                    .environment(\.defaultMinListRowHeight, 1)
                    .onAppear {
                        UITableView.appearance().separatorStyle = .none
                        UITableView.appearance().separatorColor = .clear
                    }
            }
            .navigationTitle("Fruit List")
        }
    }
    func delete(_ index: Int) {
        self.items.remove(at: index)
    }
}

At the top, we define a Person struct that contains the details of each person. Then, we create an array with three people. We use GeometryReader to calculate the card width as a percentage of the screen width. The iteration is performed over half the length of the items since we are displaying two elements per row. Note that if the number of items is odd, the last element is a Divider. When the application starts, we modify the list properties to remove the line separators.

Finally, we define the delete function, which removes an element at the specified index. This function is passed as a property to the card view.

Replace my information and image with yours, and have fun with it!

Note: English is not my native language, so I’m sorry for some errors. I appreciate if your correct me. Only the image is by AI.

share this post with friends

Picture of Nicola De filippo

Nicola De filippo

I'm a software engineer who adds to the passion for technologies the wisdom and the experience without losing the wonder for the world. I love to create new projects and to help people and teams to improve

Leave a comment

Your email address will not be published. Required fields are marked *

Who I am

I'm a software engineer who adds to the passion for technologies the wisdom and the experience without losing the wonder for the world. I love to create new projects and to help people and teams to improve.

Follow Me Here

Get The Latest Updates

Periodically receive my super contents on coding and programming

join the family;)

Recent Posts