I want to allow the default row movement in a UITableView
without it being in editing mode, and without compromising the default behaviour of the UITableView
.
The image above displays a cell in editing mode, with movement enabled.
I tried simply running for (UIView *subview in cell.subviews)
(while my UITableView
was in editing mode), but the button didn't turn up:
<UITableViewCellScrollView: 0x8cabd80; frame = (0 0; 320 44); autoresize = W+H; gestureRecognizers = <NSArray: 0x8c9ba20>; layer = <CALayer: 0x8ca14b0>; contentOffset: {0, 0}>
How can allow/add the movement "button" without enabling editing mode in my UITableView
?
Creating and adding a UIButton
with the default function
for movement is also an option.
And you can use the tableview's editing property to distinguish how the cell should look like in your tableView:cellForRowAtIndexPath: method. So even turning off the move-functionality is easier by setting your tableview back to editing = NO , the move-icon would disappear and the accessoryType symbol shows up again.
Overview. Table views in iOS display rows of vertically scrolling content in a single column. Each row in the table contains one piece of your app's content. For example, the Contacts app displays the name of each contact in a separate row, and the main page of the Settings app displays the available groups of settings ...
To use the tableview, we need to set its delegate and data source properties. The tableview is a data-driven object, i.e., it gets the data to be shown from the data source object. In the real-world applications, the data source object contains the data which is returned by an API call from the database server.
I actually do something similar for one of my apps. It uses the delegate methods for table editing and a bit of 'tricking' the user. 100% built-in Apple functionality.
1 - Set the table to editing (I do it in viewWillAppear)
-(void)viewWillAppear:(BOOL)animated{
[super viewWillAppear:animated];
[self.tableView setEditing:YES];
}
2 - Hide the default accessory icon:
-(UITableViewCellEditingStyle)tableView:(UITableView *)tableView
editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath{
//remove any editing accessories (AKA) delete button
return UITableViewCellAccessoryNone;
}
3 - Keep editing mode from moving everything to the right (in the cell)
-(BOOL)tableView:(UITableView *)tableView shouldIndentWhileEditingRowAtIndexPath:(NSIndexPath *)indexPath{
return NO;
}
4 - At this point you should be able to drag the cells around without it looking like it is in editing mode. Here we trick the user. Create your own "move" icon (three lines in the default case, whatever icon you want in your case) and add the imageView right where it would normally go on the cell.
5 - Finally, implement the delegate method to actually rearrange your underlying datasource.
-(void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)sourceIndexPath toIndexPath:(NSIndexPath *)destinationIndexPath{
//Get original id
NSMutableArray *originalArray = [self.model.items objectAtIndex:sourceIndexPath.section];
Item * original = [originalArray objectAtIndex:sourceIndexPath.row];
//Get destination id
NSMutableArray *destinationArray = [self.model.items objectAtIndex:destinationIndexPath.section];
Item * destination = [destinationArray objectAtIndex:destinationIndexPath.row];
CGPoint temp = CGPointMake([original.section intValue], [original.row intValue]);
original.row = destination.row;
original.section = destination.section;
destination.section = @(temp.x);
destination.row = @(temp.y);
//Put destination value in original array
[originalArray replaceObjectAtIndex:sourceIndexPath.row withObject:destination];
//put original value in destination array
[destinationArray replaceObjectAtIndex:destinationIndexPath.row withObject:original];
//reload tableview smoothly to reflect changes
dispatch_async(dispatch_get_main_queue(), ^{
[UIView transitionWithView:tableView duration:duration options:UIViewAnimationOptionTransitionCrossDissolve animations:^{
[tableView reloadData];
} completion:NULL];
});
}
William Falcon's answer in swift 3
1 - Set the table to editing (I do it in viewWillAppear)
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated: animated)
tableView.setEditing(true, animated: false)
}
2 - Hide the default accessory icon:
override func tableView(_ tableView: UITableView, editingStyleForRowAt indexPath: IndexPath) -> UITableViewCellEditingStyle {
return .none
}
3 - Keep editing mode from moving everything to the right (in the cell)
override func tableView(_ tableView: UITableView, shouldIndentWhileEditingRowAt indexPath: IndexPath) -> Bool {
return false
}
4 - Not required in swift 3
5 - Reorder your array
Extra Note
If you want to have your table cells selectable, add the following code within viewWillAppear()
function.
tableView.allowsSelectionDuringEditing = true
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