You can achieve this behavior if you're not actually using a section header, but have a custom item act as one.
By setting .moveDisabled()
to true
the item can't be moved. You can then style the header the way you want.
Here's a small example i've tried out.
class SelectionViewModel: ObservableObject {
struct Item {
let title: String
let isHeader: Bool
}
@Published var sections: [Item] = [
.init(title: "Selected", isHeader: true),
.init(title: "A", isHeader: false),
.init(title: "B", isHeader: false),
.init(title: "C", isHeader: false),
.init(title: "Unselected", isHeader: true),
.init(title: "D", isHeader: false),
.init(title: "E", isHeader: false),
.init(title: "F", isHeader: false),
]
}
struct SelectionView: View {
@ObservedObject var selectionViewModel: SelectionViewModel
var body: some View {
List {
ForEach(selectionViewModel.sections, id: \.title) { item in
if item.isHeader {
Text("Section header \(item.title)")
.moveDisabled(true)
.frame(maxWidth: .infinity, alignment: .leading)
.padding([.top, .bottom])
.background(Color.gray)
} else {
Text(item.title)
.moveDisabled(item.isHeader)
}
}.onMove(perform: { indices, newOffset in
print("should move")
})
}.environment(\.editMode, .constant(.active))
}
}
struct SelectionView_Previews: PreviewProvider {
static var previews: some View {
SelectionView(selectionViewModel: .init())
}
}