swiftui

Rounded corners and border for a SwiftUI List Section


I want to create the following design in SwiftUI. I am currently using a list and creating a section that contains cells like so.

List {
    Section {
        ForEach(titles) { title in
            Cell(title: title)
        }
    }
}

When I apply a modifier like a border to the section it applies it to all the views contained in the Section. I want to have that border around the entire Section with a corner radius of 10. The closest I have got to creating the desired design is by not using a List but instead using a VStack and applying the following modifiers

VStack {
    ForEach(titles) { title in
        Cell(title: title)
    }
}
.overlay(RoundedRectangle(cornerRadius: 10)
            .stroke(.gray, lineWidth: 2))

I discovered however that this is not a smart approach as the List uses reusable cells and in the case of VStack they do not. Is it possible to create the wanted design with a List in SwiftUI? I do not want to opt for the default list style provided by Apple


Solution

  • Code Preview

    Just Copy paste this code and customise it as per your needs, enjoy

    import SwiftUI
    
    struct CustomizeListView: View {
    
    var titles = ["First Section" : ["Manage your workout", "View recorded workouts", "Weight tracker", "Mediation"], "Second Section" : ["Your workout", "Recorded workouts", "Tracker", "Mediations"]]
    
    
    var body: some View {
        List {
            ForEach(titles.keys.sorted(by: <), id: \.self){ key in
                Section(key) {
                    VStack(alignment: .leading, spacing: 0){
                        ForEach(titles[key]!, id: \.self) { title in
                            HStack{
                                Text(title)
                                Spacer()
                                Image(systemName: "arrow.right")
                            }//: HSTACK
                            .padding(20)
                            Divider()
                        }//: LOOP
                    }//: VSTACK
                    .overlay(
                        RoundedRectangle(cornerRadius: 10, style: .circular).stroke(Color(uiColor: .tertiaryLabel), lineWidth: 1)
                    )
                    .foregroundColor(Color(uiColor: .tertiaryLabel))
                }//: SECTION
            }//: LOOP
        }//: LIST
        .listStyle(InsetListStyle())
    }
    }
    
    struct CustomizeListView_Previews: PreviewProvider {
    static var previews: some View {
        CustomizeListView()
    }
    }