Вот как я решил проблему:
Во-первых, у меня есть представление, в какую область я буду бросать предметы. Его высота составляет несколько пикселей, и он находится «между» уже существующими элементами.
Этот вид имеет состояние hovered
. Когда он установлен в true, представление имеет ореол выделения и большую высоту.
struct DropableView: View {
@State var hovered: Bool = false
var body: some View {
Rectangle()
.stroke(self. hovered ? Color.accentColor : Color.clear,
lineWidth: 3.0)
.frame(height: (hovered ? 20.0 : 5.0) )
.onDrop(of: [UTI_myOwn_UTI],
delegate: DropDelegate(hovered: self.$hovered))
}
}
Затем нам нужен делегат отбрасывания, который при вводе / выходе мышью изменит состояние так, чтобы вид redr aws. Убедитесь, что изменение состояния выполнено в основном потоке, так как он перерисовывает пользовательский интерфейс.
struct DropDelegate: DropDelegate {
@Binding var hovered: Bool
func dropEntered(info: DropInfo) {
DispatchQueue.main.async {
self. hovered = true
}
}
func dropExited(info: DropInfo) {
DispatchQueue.main.async {
self. hovered = false
}
}
}
Обратите внимание, что я не нашел, как анимировать изменение. Если кто-то хочет уточнить ...
Конечно, вам нужно предоставить метод validateDrop(info:)
и performDrop(info:)
, чтобы ваша капля могла что-то сделать, и начать перетаскивание с модификатором .onDrag и NSItemProvider, но это не топи c здесь.