5

I am having a hard time removing all padding from my cells in MacOS using SwiftUI. I can't seem to be able to do it even in Apple's Code!

https://developer.apple.com/tutorials/swiftui/creating-a-macos-app

For example, inside the LandMarkList of the MacLandmarks folder in Xcode, I have put a .listRowInsets(EdgeInsets()) at the end of the forEach so that the code looks like this:

struct LandmarkList: View {
    @EnvironmentObject private var userData: UserData
    @Binding var selectedLandmark: Landmark?
    @Binding var filter: FilterType

    var body: some View {
        List(selection: $selectedLandmark) {
            ForEach(userData.landmarks) { landmark in
                if (!self.userData.showFavoritesOnly || landmark.isFavorite)
                    && (self.filter == .all
                        || self.filter.category == landmark.category
                        || (self.filter.category == .featured && landmark.isFeatured)) {
                    LandmarkRow(landmark: landmark).tag(landmark)
                        .background(Color.red)
                }
            }
            .listRowInsets(EdgeInsets())
        }
    }
}

I have also put a red background color in each cell. This is the result I am getting:

Spaces top and bottom

The point is that I just can't seem to get rid of the vertical space between the cells of this list. All solutions I have seen seem to mention iOS for this, but I want to do this in Mac OS (which should have the same behavior, but it doesn't).

0

1 Answer 1

1

Here is a demo of possible solution (tested with Xcode 11.4 / macOS 10.15.6).

Note: if it will be needed to have several active Lists (ie. NSTableView) and some of them should have intercell spacing (aka separators) then they should be done by SwiftUI instruments, because this approach disables intercell spacing for all visible Lists

demo

var body: some View {
    VStack {
        Text("Selected: \(selectedPerson ?? "<none>")")
        List(selection: $selectedPerson) {
             ForEach(persons, id: \.self) { person in
                Text(person)
             }
             .listRowBackground(Color.red)
             .frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .leading)
        }.border(Color.green)
        .onReceive(NotificationCenter.default.publisher(for: NSView.frameDidChangeNotification)) {
            guard let tableView = $0.object as? NSTableView else { return }
            tableView.intercellSpacing = .zero
        }
    }
}
Sign up to request clarification or add additional context in comments.

4 Comments

Is there any way to remove the separators, too?
I tried your solution. I found 2 things: 1. listRowInsets does absolutely nothing. 2. There are no separators! I ran the app and clicked on Xcode's View Debugger. Between the cells there are are no separators, only padding!
This works, but let me make 3 observations: 1. Apple's listRowsInsets is bugged and not working on macOS? 2. This is the only way but it's inefficient (the notification will be called on every frame update from every view inside the app!). 3. It would be better just to use NSTableView and just wrap it around a SwiftUI View, am I correct? I am trying to display a list of hundreds of thousands of items.
List { Text("Row") } .listStyle(PlainListStyle())

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.