When my table view is in edit mode, the red (-) buttons appear.
When the user taps one of them the [Delete] button appears.
When the user taps on [Delete] I first check a few things (partly online). This delete may not be allowed.
When deleting that cell is not allowed, how do I hide the [Delete] button and let the red (|) button become a (-) again in an animated way? So, I don't want my whole table to leave editing state.
To get the actual animation (Instead of the UITableViewRowAnimationRight/UITableViewRowAnimationAutomatic) animations, just do
[self.tableView beginUpdates];
[self.tableView setEditing:NO animated:NO];
[self.tableView setEditing:YES animated:NO];
[self.tableView endUpdates];
beginUpdates and endUpdates provide the animation, and the tableView is just switched from not editing to editing instantly, which closes the delete button.
Hope this helps!
I've run into this issue myself where I may bring up an alert view to prompt the user further and wish to reset the delete button if they choose not to proceed. This seems like the easiest approach, assuming deleteIndexPath is the index path of the row selected for deletion:
[self.tableView reloadRowsAtIndexPaths:#[deleteIndexPath] withRowAnimation:UITableViewRowAnimationAutomatic];
I now see that you want to disable delete for only certain cells. You can do this in a couple of ways:
tableView:canEditRowAtIndexPath method: Return NO where you want DELETES to be DISABLED.
tableView:canMoveRowAtIndexPath: Return YES where you want to allow reordering.
You may want to think about sub-classing UITableViewCell to give it some ability to maintain its own state (so the cell knows if delete is allowed or not. Then you can interrogate the actual cell instance and determine if you should enable delete even after the list may be re-ordered.
To hide any icon in whole table view, then in your controller just ,
override EditingStyleForRow and return UITableViewCellEditingStyle.None
None: will hide any icon of left of items of table view,
delete: will show remove icon
Insert: will show add icon
Related
I have a tableView with some questions that a user can reorder so I have set the property setEditing to YES
[questionTableView setEditing:YES animated:YES];
also I donot want my user to delete any of the rows neither add so I have returned the UITableViewEdtitingStyle to UITableViewCellEditingStyleNone; in its delegate function.
However, the cell has got a lot of space at the left which I need to remove. How can i do that ?
I have a UITableView where I am using the swipe to delete feature to give the user the option to delete the row. However, I've also implemented an alert view that is triggered when the user selects delete, asking the user if they are sure, with two buttons, yes or no. If the user presses yes, the row is deleted, and this is working fine.
However, my problem is that when the user selects no, I am unable to animate the movement of the table cell to return to it's normal, original state while hiding the delete button that it revealed. My problem is that I want the row to do this after the user presses no on the alert, and for the animation to smooth, just as it worked when the user swiped it initially.
The code I have is the following:
- (void) cancelDelete {
//[self.tableView reloadData];
//NSLog(#"the indexpath is: %# ", self.myIndexPath);
//[self.tableView deselectRowAtIndexPath:self.myIndexPath animated:YES];
[self.tableView reloadRowsAtIndexPaths:#[self.deletedRowIndexPath] withRowAnimation:UITableViewRowAnimationRight];
}
I have left the commented lines in place to show you what I have used/am using.
[self.tableView reloadData] returns the cell back to it's original state, but there is no sliding animation of the cell to the right, such that it gradually hides the delete button. [self.tableView reloadRowsAtIndexPaths:#[self.myIndexPath] withRowAnimation:UITableViewRowAnimationRight] is what works the closest, but unfortunately, it causes the cell to jerk to the left, and then slide to the right, and I don't want this initial jerking movement. I honestly thought that [self.tableView deselectRowAtIndexPath:self.myIndexPath animated:YES] would work, but unfortunately, it doesn't do anything when it is called. What is it I am doing wrong?
Reloading is completely the wrong strategy (as you've discovered). Swiping to delete has put the table view cell into editing mode. What you want to do is put it back again so that it is no longer in editing mode.
There are various ways to do this. You might be able to call tableView:commitEditingStyle:forRowAtIndexPath:. You might be able to call setEditing:animated:. In any case, abandon your concentration on reload (which is about data) and start experimenting with editing mode.
So when the user selects a row, I put the selection on another thread for performance reasons. When I take it off of the main thread, the row is deselected for a few seconds and the pushed to the next view. Those few seconds when the row is deselected and taken off of the main thread, the user has the option to rapidly click the row again, and again - forcing the app to potentially crash. So my question is how would I deselect user interaction on the table row inside of the didSelectRowAtIndexPath method? Now, please acknowledge I don't want to disable user interaction before the a row is selected. I only am looking to disable user interaction on the cell after the row has been selected. Thanks!
Make an instance variable NSIndexPath selectedPath;
Add
[[self.tableView cellForRowAtIndexPath:indexPath] setUserInteractionEnabled:NO];
selectedPath = indexPath;
to your didSelectRowAtIndexPath and in performSegueWithIdentifier (assuming you are using storyboards) add
[[self.tableView cellForRowAtIndexPath:self.selectedPath] setUserInteractionEnabled:YES];
I use a UITableView to display a list of items, and when a row is selected I show that item in a detail view next to it (using a split view controller).
As the selection in the table view changes I want my detail view to change as well, which is of course standard behavior and it works flawlessly... except when no row is selected anymore in the table view.
Users can for example delete a row from the table view, and during and also after that deletion there will be no selected row in the table view. Of course after a row is deleted I let my detail view controller know, but during the editing process in the table view, when no row is selected, my detail view controller does not know this.
I tried to use the UITableViewSelectionDidChangeNotification but that only gets sent when the user selects a different row, not when a deselection occurs.
How can I be notified of the fact that the table view switches from having a row selected to having no selection at all?
EDIT:
As a temporary solution, I tried renaming the Edit-button to "Reorder" and only allowing moving rows from A to B but without allowing the deletion controls, but this can not be done, there is no move control without enabling editing on a row. The thing is, I do get a pointer to a row that is up for moving, so I can keep that selected. I do not get this pointer for a row up for deletion, so no go for me. I always want to know what row a user works on, and keep that row selected at all times.
I may have to resort to ditching the standard editing behavior and adding my own buttons and methods for it. Or see what gestures can do for me to capture touches on any row...
There is a property indexPathForSelectedRow. I'm not sure what it would return when there is no selected row, but it may return nil or something like that, which you could use as a trigger to know if there are any rows selected. Something like
if (myTable.indexPathForSelectedRow == nil)
{
//do something here to account for no rows being selected
}
else
{
//do stuff here to set up your detail view
}
Let me know if this works for you.
How are you implementing the deletion of rows? Are you implementing the following data source method?
tableView:commitEditingStyle:forRowAtIndexPath:
You can have a property like
NSIndexPath *selectedIndexPath
and set it to nil when a row is being deleted.
Example:
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
//select another row in your table
[tableView selectRowAtIndexPath:*indexPathOfTheRowToBeSelected* animated:YES scrollPosition:UITableViewScrollPositionNone];
//then delete row from data source
}
The method above will be called when the user touches the delete button on the table he/she has selected to delete.
Okay I misread what you were asking at first, I'm pretty sure what you want is either – tableView:willDeselectRowAtIndexPath: or – tableView:didDeselectRowAtIndexPath:. These methods will be triggered automatically when the user deselects a row (either right before the row is deselected or right after, respectively). Implement one of these in your table view delegates code, and you'll know whenever a row gets deselected, and you can put your code to select the next row or whatever you want in one of these methods.
I struggled with this as well. Turns out that when the "Edit" button is hit, all rows are deselected at that point. You can override setEditing:animated: to detect when it is hit, but you must call [super setEditing:editing animated:animated] before you return.
See this link for where I found this:
How can i identify self.editButtonItem button's clicked event?
I'm building a view controller that is very similar to the Contacts app ABPersonViewController in editing mode.
I have a UITableView filled with Custom UITableViewCells which contain a UITextField where the user can enter a phone number
I have a situation where if someone starts entering in a new phone number (in the last cell of the section), a new empty table view cell is added to the bottom of the table, and the editing style of the current table view cell is set to UITableViewCellEditingStyleDelete, like in the Contacts app in the same situation.
My problem is that I don't know how to change the editing style of the UITableViewCell without reloading it. The problem with reloading it is that its UITextField that is currently being edited will be released, dismissing the keyboard.
Is there a way to change the editing style of the UITableViewCell without reloading it? Or another way of accomplishing what I want?
Yes, just use the UITableViewCell method setEditing:animated:.
I was able to accomplish what I wanted by following the answer here:
https://stackoverflow.com/a/5664207/472344
I have successfully set editing cell with multiple selection applying below code:
[self.tableView setEditing:YES animated:YES];
self.tableView.allowsMultipleSelectionDuringEditing = YES;
// Add these two lines can fix icon issue.(First time enter edit mode still show delete icon.)
[self.tableView beginUpdates];
[self.tableView endUpdates];