Here’s how you can develop a contact list with each contact displayed in a row, using HStack to arrange the profile picture and contact information in SwiftUI:

Code Implementation

import SwiftUI

struct Contact: Identifiable {
    let id = UUID()
    let name: String
    let email: String
    let profilePicture: Image
}

struct ContactRow: View {
    let contact: Contact
    
    var body: some View {
        HStack {
            contact.profilePicture
                .resizable()
                .aspectRatio(contentMode: .fill)
                .frame(width: 50, height: 50)
                .clipShape(Circle())
                .overlay(Circle().stroke(Color.gray, lineWidth: 1))
                .shadow(radius: 2)
            
            VStack(alignment: .leading) {
                Text(contact.name)
                    .font(.headline)
                Text(contact.email)
                    .font(.subheadline)
                    .foregroundColor(.gray)
            }
            .padding(.leading, 10)
        }
        .padding(.vertical, 5)
    }
}

struct ContactListView: View {
    @State private var contacts: [Contact] = [
        Contact(name: "John Doe", email: "john@example.com", profilePicture: Image(systemName: "person.fill")),
        Contact(name: "Jane Smith", email: "jane@example.com", profilePicture: Image(systemName: "person.fill")),
        Contact(name: "Alex Johnson", email: "alex@example.com", profilePicture: Image(systemName: "person.fill"))
    ]
    @State private var isShowingSheet = false
    
    var body: some View {
        NavigationView {
            List(contacts) { contact in
                ContactRow(contact: contact)
            }
            .navigationTitle("Contacts")
            .toolbar {
                ToolbarItem(placement: .navigationBarTrailing) {
                    Button(action: {
                        isShowingSheet.toggle()
                    }) {
                        Image(systemName: "plus")
                    }
                }
            }
        }
        .sheet(isPresented: $isShowingSheet) {
            AddContactView(contacts: $contacts)
                .presentationDetents([.height(200)])
        }
    }
}

struct AddContactView: View {
    @Binding var contacts: [Contact]
    @Environment(\.dismiss) var dismiss
    
    @State private var name = ""
    @State private var email = ""
    
    var body: some View {
        VStack {
            Text("Add New Contact")
                .font(.headline)
                .padding(.bottom, 20)
            
            TextField("Name", text: $name)
                .textFieldStyle(RoundedBorderTextFieldStyle())
                .padding(.horizontal)
            
            TextField("Email", text: $email)
                .textFieldStyle(RoundedBorderTextFieldStyle())
                .padding(.horizontal)
                .keyboardType(.emailAddress)
                .autocapitalization(.none)
            
            Button("Submit") {
                let newContact = Contact(name: name, email: email, profilePicture: Image(systemName: "person.fill"))
                contacts.append(newContact)
                dismiss()
            }
            .padding(.top, 10)
            .disabled(name.isEmpty || email.isEmpty)
        }
        .padding()
    }
}

#Preview {
    ContactListView()
}

Explanation

  1. Contact Model:
    • Contact: A simple model representing a contact, conforming to the Identifiable protocol to uniquely identify each contact.
  2. ContactRow View:
    • ContactRow: A view that displays a single contact using HStack to arrange the profile picture and contact information.
    • Profile picture: Displayed using Image, made resizable and clipped into a circle with a border and shadow.
    • Contact information: Arranged in a VStack, showing the contact’s name and email.
  3. ContactListView:
    • ContactListView: A view that displays a list of contacts using List and NavigationView for navigation.
    • contacts: An array of sample contacts.
    • Each ContactRow in the list represents a contact.