我有两个带有简单项目的列表。我可以使用以下代码重新排列列表中的项目。我希望能够将一个项目从一个列表中拖放到另一个列表中。不知道我需要启用什么才能实现这一目标。照原样,我可以在整个屏幕上从一个列表中拖动某些内容,但不能将其拖放到任何位置,除非在其自己的列表中。如果我在其他任何地方释放阻力,它就会飞回其原始位置。
很显然,我需要添加一些东西以实现所需的行为;任何关于所需内容的想法(不一定要使用.onMove
都在同一列表中)将得到极大的赞赏。
struct ContentView: View {
@State private var users1 = ["AAA", "BBB", "CCC"]
@State private var users2 = ["DDD", "EEE", "FFF"]
@State private var isEditable = true
var body: some View {
HStack {
Spacer()
List {
ForEach(users1, id: \.self) { user in
Text(user)
.background(Color(.yellow))
}
.onMove(perform: move1)
}
.environment(\.editMode, isEditable ? .constant(.active) : .constant(.inactive))
Spacer()
List {
ForEach(users2, id: \.self) { user in
Text(user)
.background(Color(.orange))
}
.onMove(perform: move2)
}
.environment(\.editMode, isEditable ? .constant(.active) : .constant(.inactive))
Spacer()
}
}
func move1(from source: IndexSet, to destination: Int) {
users1.move(fromOffsets: source, toOffset: destination)
}
func move2(from source: IndexSet, to destination: Int) {
users2.move(fromOffsets: source, toOffset: destination)
}
}
答案 0 :(得分:2)
我认为SwiftUI不可能做到这一点。这段代码显示了如何使用两个UITableViews
。我希望您可以改善它以实现您想要的。
首先创建一个完成所有魔术的类。您需要导入UIKit
和MobileCoreServices
。
class TableViewController: UIViewController, UITableViewDataSource, UITableViewDelegate, UITableViewDragDelegate, UITableViewDropDelegate {
var leftTableView = UITableView()
var rightTableView = UITableView()
var removeIndex = IndexPath()
var leftItems: [String] = [
"Hello",
"What",
"is",
"happening"
]
var rightItems: [String] = [
"I",
"don't",
"know"
]
func tableView(_ tableView: UITableView, itemsForBeginning session: UIDragSession, at indexPath: IndexPath) -> [UIDragItem] {
let string = tableView == leftTableView ? leftItems[indexPath.row] : rightItems[indexPath.row]
self.removeIndex = indexPath
guard let data = string.data(using: .utf8) else { return [] }
let itemProvider = NSItemProvider(item: data as NSData, typeIdentifier: kUTTypePlainText as String)
return [UIDragItem(itemProvider: itemProvider)]
}
func tableView(_ tableView: UITableView, performDropWith coordinator: UITableViewDropCoordinator) {
let destinationIndexPath: IndexPath
if let indexPath = coordinator.destinationIndexPath {
destinationIndexPath = indexPath
} else {
let section = tableView.numberOfSections - 1
let row = tableView.numberOfRows(inSection: section)
destinationIndexPath = IndexPath(row: row, section: section)
}
coordinator.session.loadObjects(ofClass: NSString.self) { items in
guard let strings = items as? [String] else {
return
}
var indexPaths = [IndexPath]()
for (index, string) in strings.enumerated() {
let indexPath = IndexPath(row: destinationIndexPath.row + index, section: destinationIndexPath.section)
if tableView == self.leftTableView {
self.leftItems.insert(string, at: indexPath.row)
} else {
self.rightItems.insert(string, at: indexPath.row)
}
indexPaths.append(indexPath)
}
if tableView == self.leftTableView {
self.rightItems.remove(at: self.removeIndex.row)
self.rightTableView.deleteRows(at: [self.removeIndex], with: .automatic)
} else {
self.leftItems.remove(at: self.removeIndex.row)
self.leftTableView.deleteRows(at: [self.removeIndex], with: .automatic)
}
tableView.insertRows(at: indexPaths, with: .automatic)
}
}
override func viewDidLoad() {
super.viewDidLoad()
leftTableView.dataSource = self
rightTableView.dataSource = self
leftTableView.frame = CGRect(x: 0, y: 40, width: 150, height: 400)
rightTableView.frame = CGRect(x: 150, y: 40, width: 150, height: 400)
leftTableView.register(UITableViewCell.self, forCellReuseIdentifier: "Cell")
rightTableView.register(UITableViewCell.self, forCellReuseIdentifier: "Cell")
view.addSubview(leftTableView)
view.addSubview(rightTableView)
leftTableView.dragDelegate = self
leftTableView.dropDelegate = self
rightTableView.dragDelegate = self
rightTableView.dropDelegate = self
leftTableView.dragInteractionEnabled = true
rightTableView.dragInteractionEnabled = true
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
if tableView == leftTableView {
return leftItems.count
} else {
return rightItems.count
}
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath)
if tableView == leftTableView {
cell.textLabel?.text = leftItems[indexPath.row]
} else {
cell.textLabel?.text = rightItems[indexPath.row]
}
return cell
}
}
然后将其包装:
struct TableView: UIViewControllerRepresentable {
func makeUIViewController(context: Context) -> TableViewController {
let v = TableViewController()
return v
}
func updateUIViewController(_ viewController: TableViewController, context: Context) {
}
}
最后使用它:
struct ContentView: View {
var body: some View {
VStack {
TableView()
}
}
}
我希望这会有所帮助。