I have a SwiftUI List that's a sidebar on macOS. For its items I have added the dropDesternation modifier like this:
.dropDestination(for: URL.self) { urls, _ in
for url in urls {
//... adding urls to destination
}
}
return true
} isTargeted: { inDropArea in
if inDropArea {
highlightedItem = item
} else {
highlightedItem = nil
}
}
By default if the cursor is above the item I get no effect, but I want the same effect like using NSOutlineView in AppKit. Here's an example from the Finder:

As you can see I have implemented highlightedItem in the code above. I can use it to check if an item is targeted and draw a background:
.background {
if item == highlightedItem {
RoundedRectangle(cornerRadius: 5)
.fill(Color.blue)
.frame(maxWidth: .infinity, maxHeight: .infinity)
}
}
But that does not look quite the same:

Interestingly the effect I want is the same you get if you use a selection for the sidebar list like: List(selection: $selectedItem)
There must be a native way to do this so I don't have to fake it and get something that does not look quite right.
Having the List elements be selectable and triggering that selection temporarily seems to work quite nicely.
For example ...
let Bands: Array<String> = [
"Beatles", "Rolling Stones", "Animals", "Beach Boys", "Doors",
]
struct ContentView: View {
@State var selection: String? = nil
@State var dropSelectionCache: String? = nil
var body: some View {
VStack {
Text("Drag text on onto band to trigger highlighting")
List(Bands, id: \.self, selection: $selection) { band in
Text(band)
.dropDestination(for: String.self) { _, _ in
true
} isTargeted: { (isTarget: Bool) in
if isTarget {
dropSelectionCache = selection
withAnimation {
selection = band
}
} else {
withAnimation {
selection = dropSelectionCache
}
}
}
}
}
}
}
Here's a gif illustrating the code in operation on Ventura (apologies for slightly shakey screen recording - that's me an and not the code :-/ )

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With