Reputation: 64834
I have a UITableView with draggable rows and I can add/remove items. The datasource is a NSMutableArray.
Now, if I move the row with "Add new functionality" the app crashes because the dataSource is smaller since such row has not been added yet.
So I've modified this code:
- (BOOL)tableView:(UITableView *)tableView canMoveRowAtIndexPath:(NSIndexPath *)indexPath {
if (indexPath.row >= [dataList count]) return NO;
return YES;
}
And now I can't move it anymore. However I can still move the other rows after such row and consequently the code crashes.
How can I solve this ? Is there a way to disable the dragging "to" specific rows and not only from ?
thanks
Upvotes: 28
Views: 13476
Reputation: 13234
Following is the working solution for disable row from moving.
func tableView(_ tableView: UITableView, canMoveRowAt indexPath: IndexPath) -> Bool {
if indexPath.row == 0{//specify your indexpath row here....
return false
}else{
return true
}
}
Upvotes: 2
Reputation: 378
Following is the example to restrict drag and drop to 0th index of 1st section UICollectionView
:
func collectionView(_ collectionView: UICollectionView, dropSessionDidUpdate session: UIDropSession, withDestinationIndexPath destinationIndexPath: IndexPath?) -> UICollectionViewDropProposal {
if session.localDragSession != nil {
// Restricts dropping to 0th index
if destinationIndexPath?.row == 0 {
return UICollectionViewDropProposal(operation: .forbidden)
}
if collectionView.hasActiveDrag {
return UICollectionViewDropProposal(operation: .move, intent: .insertAtDestinationIndexPath)
} else {
return UICollectionViewDropProposal(operation: .copy, intent: .insertAtDestinationIndexPath)
}
}
}
func collectionView(_ collectionView: UICollectionView, itemsForBeginning session: UIDragSession, at indexPath: IndexPath) -> [UIDragItem] {
// Prevents dragging item from 0th index
if indexPath.row == 0 {
return [UIDragItem]() // Prevents dragging item from 0th index
}
let item = self.yourArray[indexPath.row]
let itemProvider = NSItemProvider(object: item)
let dragItem = UIDragItem(itemProvider: itemProvider)
dragItem.localObject = item
return [dragItem]
}
Upvotes: 7
Reputation: 8323
This is exactly what the UITableViewDelegate
method
-tableView:targetIndexPathForMoveFromRowAtIndexPath:toProposedIndexPath:
is for. Will it suit your purposes? Here's the documentation.
Upvotes: 46
Reputation: 49085
The previous answers and the documentation (see this and this, as mentioned in the other answers) are helpful but incomplete. I needed:
Without further ado, here are some
- (NSIndexPath *)tableView:(UITableView *)tableView
targetIndexPathForMoveFromRowAtIndexPath:(NSIndexPath *)sourceIndexPath
toProposedIndexPath:(NSIndexPath *)proposedDestinationIndexPath
{
return proposedDestinationIndexPath;
}
- (NSIndexPath *)tableView:(UITableView *)tableView
targetIndexPathForMoveFromRowAtIndexPath:(NSIndexPath *)sourceIndexPath
toProposedIndexPath:(NSIndexPath *)proposedDestinationIndexPath
{
return sourceIndexPath;
}
- (NSIndexPath *)tableView:(UITableView *)tableView
targetIndexPathForMoveFromRowAtIndexPath:(NSIndexPath *)sourceIndexPath
toProposedIndexPath:(NSIndexPath *)proposedDestinationIndexPath
{
if (... some condition ...) {
return sourceIndexPath;
}
return proposedDestinationIndexPath;
}
Upvotes: 27
Reputation: 7284
How to make last row fix:
- (NSIndexPath *)tableView:(UITableView *)tableView
targetIndexPathForMoveFromRowAtIndexPath:(NSIndexPath *)sourceIndexPath
toProposedIndexPath:(NSIndexPath *)proposedDestinationIndexPath
{
// get number of objects
NSUInteger numberOfObjects = [[[BNRItemStore sharedStore] allItems] count];
if ( (proposedDestinationIndexPath.row+1==numberOfObjects) || (sourceIndexPath.row+1==numberOfObjects) ) {
NSLog(@"HERE");
return sourceIndexPath;
}
else{
NSLog(@"count=%d %d", [[[BNRItemStore sharedStore] allItems] count], proposedDestinationIndexPath.row);
return proposedDestinationIndexPath;
}
}
Upvotes: 9