Layout Issue when Reordering SwiftUI Lists on macOS

Viewed 209

When reordering a SwiftUI List using drag/drop on macOS, which does not use SidebarListStyle, a large amount of blank space appears underneath the row that has been moved.

This doesn't happen on iOS or if the list style is set to SidebarListStyle.

enter image description here

Here's example code that shows the problem.

import SwiftUI

struct Item: Hashable, Identifiable {
    var id = UUID()
    var title: String
}

struct ContentView: View {
    @State var items = [
        Item(title:"Number 1"),
        Item(title:"Number 2"),
        Item(title:"Number 3"),
        Item(title:"Number 4"),
        Item(title:"Number 5"),
        Item(title:"Number 6"),
        Item(title:"Number 7"),
        Item(title:"Number 8"),
        Item(title:"Number 9"),
        Item(title:"Number 10")
    ]
    
    var body: some View {
        List {
            ForEach(items, id: \.id) { item in
                Text(item.title)
                    .frame(maxWidth: .infinity, alignment: .center)
            }
            .onMove { (indexSet, index) in
                self.items.move(fromOffsets: indexSet, toOffset: index)
            }
        }
        .listStyle(PlainListStyle())
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}

Is there any way to prevent this extra space from appearing?

1 Answers

Nasty and ugly1 but acceptable workaround for the time being:

self.items.move(fromOffsets: indexSet, toOffset: index)
let container = self.items
self.items.removeAll()
DispatchQueue.main.async {
    self.items = container
}

1Causing some flickering on mouse drop due to list reload

Related