Is there a way to prevent cells in a tableView from being moved to a different section?
The sections
have data for different types of cells, so the app crashes when the user tries to drag a cell into a different section.
I would like to only allow the user to move a cell inside the section, and not in between sections.
Relevant code is below:
override func tableView(_ tableView: UITableView, canMoveRowAt indexPath: IndexPath) -> Bool {
return true
}
override func tableView(_ tableView: UITableView, moveRowAt sourceIndexPath: IndexPath, to destinationIndexPath: IndexPath) {
let reorderedRow = self.sections[sourceIndexPath.section].rows.remove(at: sourceIndexPath.row)
self.sections[destinationIndexPath.section].rows.insert(reorderedRow, at: destinationIndexPath.row)
self.sortedSections.insert(sourceIndexPath.section)
self.sortedSections.insert(destinationIndexPath.section)
}
You will need to implement the UITableViewDelegate
method targetIndexPathForMoveFromRowAt
.
Your strategy will be to allow the move if the source and destination section
are the same. If they aren't then you can return either row 0, if the proposed destination section is less than the source section or the last row of the section if the proposed destination section is greater than the source section.
This will constrain the move to the source section.
override func tableview(_ tableView: UITableView, targetIndexPathForMoveFromRowAt sourceIndexPath: IndexPath, toProposedIndexPath proposedDestinationIndexPath: IndexPath) -> IndexPath {
let sourceSection = sourceIndexPath.section
let destSection = proposedDestinationIndexPath.section
if destSection < sourceSection {
return IndexPath(row: 0, section: sourceSection)
} else if destSection > sourceSection {
return IndexPath(row: self.tableView(tableView, numberOfRowsInSection:sourceSection)-1, section: sourceSection)
}
return proposedDestinationIndexPath
}
You can retarget the proposed destination for restriction by implementing the tableView:targetIndexPathForMoveFromRowAtIndexPath:toProposedIndexPath: method
func tableView(_ tableView: UITableView, targetIndexPathForMoveFromRowAt sourceIndexPath: IndexPath, toProposedIndexPath proposedDestinationIndexPath: IndexPath) -> IndexPath {
// Finds number of items in source group
let numberOfItems = self.tableView(tableView, numberOfRowsInSection: sourceIndexPath.section)
// Restricts rows to relocation in their own group by checking source and destination sections
if (sourceIndexPath.section != proposedDestinationIndexPath.section) {
/*
if we move the row to the not allowed upper area, it is moved to the top of the allowed group and vice versa
if we move the row to the not allowed lower area, it is moved to the bottom of the allowed group
also prevents moves to the last row of a group (which is reserved for the add-item placeholder).
*/
let rowInSourceSection = (sourceIndexPath.section > proposedDestinationIndexPath.section) ? 0 : numberOfItems - 1;
return IndexPath(row: rowInSourceSection, section: sourceIndexPath.section)
}
// Prevents moves to the last row of a group (which is reserved for the add-item placeholder).
else if (proposedDestinationIndexPath.row >= numberOfItems) {
return IndexPath(row: numberOfItems - 1, section: sourceIndexPath.section)
}
// Passing all restrictions
return proposedDestinationIndexPath
}
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