#swift #swiftui #drag-and-drop #swiftui-list
Вопрос:
Я пытался реализовать перетаскивание на a List
в SwiftUI. То , что я пытаюсь сделать, — это перетащить строку на a List
и поместить ее в ту же List
строку, как в приложении «Остатки iOS
«.
Примечание: Важно отметить, что я не пытаюсь изменить порядок списка, а скорее сделать отброшенный элемент «дочерним» в этой строке.
import SwiftUI import UniformTypeIdentifiers struct Item: Identifiable { let id = UUID() let title: String } struct EditListView: View { @State private var items: [Item] = [ Item(title: "Apple"), Item(title: "Banana"), Item(title: "Papaya"), Item(title: "Mango") ] var body: some View { VStack { List { ForEach(items) { item in Text(item.title) } .onDrop(of: [UTType.text], delegate:dropDelegate() )//doesn't work .onDrag{ NSItemProvider(item: .some(URL(string: "item")! as NSSecureCoding), typeIdentifier: String() ) } } Text("Drop Item Here..") .fontWeight(.heavy) .onDrop(of: [UTType.text], delegate:dropDelegate() )//works } } } class dropDelegate: DropDelegate { func performDrop(info: DropInfo) -gt; Bool { print("drop success") return true } }
Заскакиваю на Text
работу.
Не удается выполнить удаление строки списка.
Комментарии:
1. В вашем окончательном решении нужно ли переставлять и помещать в подсписк ? или удаление в подсписк необходимо только ?
2. Я хочу сделать КАК перемещение в подсписк, так и перестановку.
3. Я не думаю, что это ответ, но, играя с этим прошлой ночью, я обнаружил, что вы можете перетаскивать и перетаскивать между двумя соседними списками так, как хотите, без какой-либо специальной работы. Поэтому я возился с двумя возможными решениями, которые, по сути, слоили два списка и распределяли перетаскивание по ним. Одно решение не соответствовало взаимодействию перетаскивания по умолчанию в том, что оно не вызывало элемент при длительном нажатии перетаскивания (сначала нужно было переместить перетаскивание), другое не выделяло ячейку способом по умолчанию при наведении. Не уверены, представляет ли какой-либо из них интерес?
4. Идея двухуровневых списков звучит действительно интересно. В любом случае, я мог бы взглянуть на код, даже если это не полный ответ?
Ответ №1:
Похоже, что с вашим кодом есть две проблемы.
Во-первых : многие статьи в Интернете сообщают, что удаление не работает с компонентом списка, но вы можете заменить список представлением прокрутки. Затем будет вызван метод drop.
Во-вторых: если вы хотите применить действие по элементу, вы должны переместить метод удаления внутри каждого элемента.
В обновленном коде я только что добавил образец ячейки, вы можете легко воспроизвести эффект ячейки самостоятельно :
struct Sample: View { @State private var items: [Item] = [ Item(title: "Apple"), Item(title: "Banana"), Item(title: "Papaya"), Item(title: "Mango") ] var body: some View { VStack { ScrollView { ForEach(items) { item in SampleCell(item: item) .onDrop(of: [UTType.text], delegate:dropDelegate() ) .onDrag{ NSItemProvider(item: .some(URL(string: "item")! as NSSecureCoding), typeIdentifier: String() ) } } } Text("Drop Item Here..") .fontWeight(.heavy) .onDrop(of: [UTType.text], delegate:dropDelegate() )//works } } } struct SampleCell: View { var item : Item var body: some View { HStack { Text(item.title).padding() Spacer() }.frame(maxWidth:.infinity, minHeight: 60) .background(Color.gray) } }
Комментарии:
1. Эта реализация позволила бы отбрасывать и отбрасывать строки, но она удаляет функцию перестановки.
2. Итак, я думаю, что на самом деле (ноябрь 2021 года) вы не можете понять, чего хотите, потому что onMove и OnInsert доступны только в списке, а не в ScrollView.
3. Наверное, ты прав. Я видел несколько вопросов без ответа по этой же проблеме. По словам инженера технической поддержки разработчиков Apple, с которым я разговаривал сегодня, как перестановка, так и перетаскивание могут быть достигнуты с помощью
LazyVStack
(невозможно со списками). Однако, по данным DTS, пока нет документации о том, как этого добиться.