Fix drag and drop target bugs

This commit is contained in:
Maurice Parker 2019-11-21 13:22:33 -06:00
parent 7243e0e07b
commit 150e50082c
2 changed files with 46 additions and 26 deletions

View File

@ -18,45 +18,67 @@ extension MasterFeedViewController: UITableViewDropDelegate {
} }
func tableView(_ tableView: UITableView, dropSessionDidUpdate session: UIDropSession, withDestinationIndexPath destinationIndexPath: IndexPath?) -> UITableViewDropProposal { func tableView(_ tableView: UITableView, dropSessionDidUpdate session: UIDropSession, withDestinationIndexPath destinationIndexPath: IndexPath?) -> UITableViewDropProposal {
if tableView.hasActiveDrag { guard let destIndexPath = destinationIndexPath,
if let destIndexPath = destinationIndexPath, let destNode = dataSource.itemIdentifier(for: destIndexPath) { destIndexPath.section > 0,
if destNode.representedObject is Folder { tableView.hasActiveDrag,
return UITableViewDropProposal(operation: .move, intent: .insertIntoDestinationIndexPath) let destNode = dataSource.itemIdentifier(for: destIndexPath),
} else { let destCell = tableView.cellForRow(at: destIndexPath) else {
return UITableViewDropProposal(operation: .move, intent: .insertAtDestinationIndexPath) return UITableViewDropProposal(operation: .forbidden)
}
}
} }
return UITableViewDropProposal(operation: .forbidden)
if destNode.representedObject is Folder && session.location(in: destCell).y >= 0 {
return UITableViewDropProposal(operation: .move, intent: .insertIntoDestinationIndexPath)
} else {
return UITableViewDropProposal(operation: .move, intent: .insertAtDestinationIndexPath)
}
} }
func tableView(_ tableView: UITableView, performDropWith dropCoordinator: UITableViewDropCoordinator) { func tableView(_ tableView: UITableView, performDropWith dropCoordinator: UITableViewDropCoordinator) {
guard let dragItem = dropCoordinator.items.first?.dragItem, guard let dragItem = dropCoordinator.items.first?.dragItem,
let sourceNode = dragItem.localObject as? Node, let sourceNode = dragItem.localObject as? Node,
let sourceIndexPath = dataSource.indexPath(for: sourceNode),
let webFeed = sourceNode.representedObject as? WebFeed, let webFeed = sourceNode.representedObject as? WebFeed,
let destinationIndexPath = dropCoordinator.destinationIndexPath else { let destIndexPath = dropCoordinator.destinationIndexPath else {
return return
} }
// Based on the drop we have to determine a node to start looking for a parent container. let isFolderDrop: Bool = {
let destNode: Node = { if let propDestNode = dataSource.itemIdentifier(for: destIndexPath), let propCell = tableView.cellForRow(at: destIndexPath) {
if destinationIndexPath.row == 0 { return propDestNode.representedObject is Folder && dropCoordinator.session.location(in: propCell).y >= 0
return coordinator.rootNode.childAtIndex(destinationIndexPath.section)!
} else {
let movementAdjustment = sourceIndexPath > destinationIndexPath ? 1 : 0
let adjustedDestIndexPath = IndexPath(row: destinationIndexPath.row - movementAdjustment, section: destinationIndexPath.section)
return dataSource.itemIdentifier(for: adjustedDestIndexPath)!
} }
return false
}()
// Based on the drop we have to determine a node to start looking for a parent container.
let destNode: Node? = {
if destIndexPath.row == 0 {
return coordinator.rootNode.childAtIndex(destIndexPath.section)!
} else {
if isFolderDrop {
return dataSource.itemIdentifier(for: destIndexPath)
} else {
if destIndexPath.row > 0 {
return dataSource.itemIdentifier(for: IndexPath(row: destIndexPath.row - 1, section: destIndexPath.section))
} else {
return nil
}
}
}
}() }()
// Now we start looking for the parent container // Now we start looking for the parent container
let destParentNode: Node? = { let destParentNode: Node? = {
if destNode.representedObject is Container { if destNode?.representedObject is Container {
return destNode return destNode
} else { } else {
if destNode.parent?.representedObject is Container { if destNode?.parent?.representedObject is Container {
return destNode.parent! return destNode!.parent!
} else { } else {
return nil return nil
} }

View File

@ -353,13 +353,11 @@ class MasterFeedViewController: UITableViewController, UndoableCommandRunner {
sortedNodes.remove(at: index) sortedNodes.remove(at: index)
let movementAdjustment = sourceIndexPath < destIndexPath ? 1 : 0 if index >= sortedNodes.count {
let adjustedIndex = index - movementAdjustment
if adjustedIndex >= sortedNodes.count {
let lastSortedIndexPath = dataSource.indexPath(for: sortedNodes[sortedNodes.count - 1])! let lastSortedIndexPath = dataSource.indexPath(for: sortedNodes[sortedNodes.count - 1])!
return IndexPath(row: lastSortedIndexPath.row + 1, section: lastSortedIndexPath.section) return IndexPath(row: lastSortedIndexPath.row + 1, section: lastSortedIndexPath.section)
} else { } else {
return dataSource.indexPath(for: sortedNodes[adjustedIndex])! return dataSource.indexPath(for: sortedNodes[index])!
} }
} }