swiftuiswiftui-navigationview

How to hide the divider line below the navigation bar?


I need to remove the Divider below the NavigationView, this is happening when I am set .listStyle(.plain) because I need to provide manual insets for the List. I have also tried with embedding List with VStack but didn't helped, when adding Text inside VStack I can get rid of the Divider line, but I need to achieve this without the Text. Kindly help me to achieve this.

Current Output Image

Please find the code snippet of SwiftUI:

import SwiftUI

struct ContentView: View {
    var apiHandler = APIHandler.shared
    
    @State var users = [User]()
    
    var body: some View {
        NavigationView {
            List {
                
                //Top Horizontal Layout
                
                ScrollView(.horizontal,showsIndicators: false) {
                    HStack {
                        ForEach(users, id: \.id) { user in
                            HorizontalUserList(user: user)
                        }
                    }
                }
                
                //Vertical Layout
                ForEach(users,id: \.id) { user in
                    VerticalUserList(user: user)
                        .listRowInsets(.init(top: 20, leading: 10, bottom: 0, trailing: 0))
                }
            }
            .listStyle(.plain)
            .listSectionSeparator(.hidden,edges: .all)
            .scrollContentBackground(.hidden)
            .navigationTitle("Users")
        }
        .onAppear(perform: {
            apiHandler.getUsers {
                users = apiHandler.users
            }
        })
    }
}

struct VerticalUserList: View {
    var user : User
    
    @State var image = UIImage()
    
    var body: some View {
        HStack{
            Image(uiImage: image)
                .resizable()
                .cornerRadius(30)
                .aspectRatio(contentMode: .fit)
                .frame(width: 60,height: 60,alignment: .center)
                .onAppear(perform: {
                    guard let url = URL(string: user.avatar) else { return }
                    URLSession.shared.dataTask(with: url) { data, response, error in
                        guard let data = data else { return }
                        guard let image = UIImage(data: data) else { return }
                        DispatchQueue.main.async {
                            self.image = image
                        }
                    }.resume()
                })
            Text(user.first_name + "" + user.last_name)
                .font(.headline)
                .multilineTextAlignment(.leading)
        }
    }
}

struct HorizontalUserList: View {
    var user : User
    
    @State var image = UIImage()
    
    var body: some View {
        VStack{
            Image(uiImage: image)
                .resizable()
                .frame(width: 80,height: 80,alignment: .center)
                .cornerRadius(40)
                .aspectRatio(contentMode: .fit)
                .padding(10)
                .onAppear(perform: {
                    guard let url = URL(string: user.avatar) else { return }
                    URLSession.shared.dataTask(with: url) { data, response, error in
                        guard let data = data else { return }
                        guard let image = UIImage(data: data) else { return }
                        DispatchQueue.main.async {
                            self.image = image
                        }
                    }.resume()
                })
            Text(user.first_name + "" + user.last_name)
                .font(.headline)
                .multilineTextAlignment(.leading)
        }
    }
}

Solution

  • You can use the .listRowSeparator(.hidden) view modifier to hide the separator on a given row. However, for the first row, it will remove the top and bottom separators. You can use a Divider() to recreate the missing bottom separator.

    struct ContentView: View {
        private let horizontalUsers: [String] = Array(repeating: "Steve Jobs", count: 5)
        private let verticalUsers: [String] = Array(repeating: "John Doe", count: 5)
    
        var body: some View {
            NavigationStack {
                List {
                    VStack {
                        ScrollView(.horizontal) {
                            HStack {
                                ForEach(horizontalUsers, id: \.self) { horizontalUserName in
                                    Label(horizontalUserName, systemImage: "person.circle")
                                }
                            }
                        }
                        Divider()
                    }
                    .listRowSeparator(.hidden)
                    .listRowInsets(EdgeInsets(top: 0, leading: 16, bottom: 0, trailing: 0))
    
                    ForEach(verticalUsers, id: \.self) { name in
                        Text(name)
                    }
                }
                .listStyle(.plain)
                .navigationTitle("Users")
            }
        }
    }
    

    Here is what it looks like :

    enter image description here