UITableViewController: Swipe to delete enabled if condition is satisfied - iphone

For UIViewController reuse purpose I want to allow the "Swipe to Delete" gesture only in case that a condition is satisfied. Is there a way to achieve that?
If I add the following UITableViewController Delegate method:
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
the "Swipe to delete" is enabled but I'm not able to discriminate in which cases I want to disable this gesture

- (UITableViewCellEditingStyle)tableView:(UITableView *)aTableView
editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath {
BOOL someCondition = // figure out whether you want swipe to be available
return (someCondition) ?
UITableViewCellEditingStyleDelete : UITableViewCellEditingStyleNone;
}
Comes from the end of this section of my book:
http://www.apeth.com/iOSBook/ch21.html#_deleting_table_items

- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
{
if (UITableViewCellEditingStyleDelete==YES)
{
// here goes your code
}
}

Place your logic inside of the delegate method
- (UITableViewCellEditingStyle)tableView:(UITableView *)aTableView
editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath
For Example
To only allow editing on the odd rows:
-(UITableViewCellEditingStyle)tableView:(UITableView *)aTableView
editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath
{
if (indexPath.row % 2 == 1)
{
return UITableViewCellEditingStyleDelete;
}
else return UITableViewEditingStyleNone;
}
Percent Sign?!
This is something I love teaching just because it can be so useful in so many circumstances - in the block of code indexPath.row 2 == 1, were checking to see if the row of the indexPath is odd. Here's how it works: The percent sign is called a modulus. What is does is it performs the division much like you would on a piece of paper, then takes the remainder of the calculation - once you understand this, you see how immensely powerful it would be. You can check to see if a number is divisible by another number, for example.
In our example, we're looking at what the remainder is when we divide the row by 2. If it's 0, we know its divisible by two, therefore it's even. If it returns 1, though, the row is odd. It's an amazing tool.

Related

Add "Swipe to delete" but not in all cells

I want to add in my tableview the possibility to "swipe to delete", but I don't want this for the last cell of the table!
I can check in - (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath if the indexPath.row is the last one, but what I want is that if the user swipes on the last cell, nothing will appear (while in the others cells appears the text "delete").
I've tried this
-(NSString *)tableView:(UITableView *)tableView titleForDeleteConfirmationButtonForRowAtIndexPath:(NSIndexPath *)indexPath{
if (indexPath.row != ([array count]-1)) {
return #"delete";
}
else {
NSString *a;
return a;
}
}
but of course it doesn't works (the app crashes).
I've tried with
return #"";
but the red button appears (with no text)!
What do you suggest me?
Thanks!
Try
- (UITableViewCellEditingStyle)tableView:(UITableView *)tableView editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath
{
if ([indexPath row] == [tableView numberOfRowsInSection:[indexPath section]] - 1)
{
return UITableViewCellEditingStyleNone;
}
return UITableViewCellEditingStyleDelete;
}
The app crashes since you return an uninitialized pointer. But even then, you're doing it wrong ;-)
You want to implement tableView:editingStyleForRowAtIndexPath: and return UITableViewCellEditingStyleDelete for all cells, except for the last. You need to return UITableViewCellEditingStyleNone for the last cell to prevent that it can be deleted.

How can I make a cell movable but not deletable in a UITableView?

My aim
Hello, my problem is quite simple. I have a UITableView with a couple of cells. Some of them can be deleted (but not necessarily all of them), but all of them can be movable.
My problem
I do not understand how to realize this through the iOS SDK. Using a combination of tableView:canMoveRowAtIndexPath: and tableView:canEditRowAtIndexPath: I am only able to set a cell as deletable, and eventually movable, but not vice versa. I would like to set a cell as movable but not necessarily deletable. Is this possible?
Movable:
-(BOOL)tableView:(UITableView *)tableView canMoveRowAtIndexPath:(NSIndexPath *)indexPath
{
return YES;
}
Non-Deletable:
- (UITableViewCellEditingStyle)tableView:(UITableView *)tableView editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath
{
return UITableViewCellEditingStyleNone;
}

move row inside a UITableView

I have a UITableView that contain 3 sections, It is possible in the edit mode to change the row position just inside his section and not to another section?Actually I can move the cell to any section.
Thanks
Many correct answers but no one presented a complete and well presented reply.
Use the table view delegate method tableView:targetIndexPathForMoveFromRowAtIndexPath:toProposedIndexPath: as shown below.
- (NSIndexPath *)tableView:(UITableView *)tableView targetIndexPathForMoveFromRowAtIndexPath:(NSIndexPath *)sourceIndexPath toProposedIndexPath:(NSIndexPath *)proposedDestinationIndexPath
{
if (proposedDestinationIndexPath.section != sourceIndexPath.section)
{
return sourceIndexPath;
}
return proposedDestinationIndexPath;
}
Do not forget to do another check in your tableView:moveRowAtIndexPath:toIndexPath: data source method as shown below, you do not want to run your application logic when the destination is similar to the source.
- (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)sourceIndexPath toIndexPath:(NSIndexPath *)destinationIndexPath
{
if(sourceIndexPath == destinationIndexPath)
{
return;
}
//application logic
}
If I understand your question correctly, then yes: use
- (NSIndexPath*) tableView: (UITableView*) tableView targetIndexPathForMoveFromRowAtIndexPath: (NSIndexPath*) sourceIndexPath toProposedIndexPath: (NSIndexPath*) proposedDestinationIndexPath
like Steven and Narayanan said, you have to implement the method
- (NSIndexPath *)tableView:(UITableView *)tableView targetIndexPathForMoveFromRowAtIndexPath:(NSIndexPath *)sourceIndexPath toProposedIndexPath:(NSIndexPath *)proposedDestinationIndexPath
of your UITableView delegate.
In this method, you check the sourceIndexPath.section:
If it's the section you allow to be reordered, you return the proposedDestinationIndexPath.
If not, you return the sourceIndexPath so your tableView will not move the row.
I didn't write the code so you'll have the pleasure to practice instead of copy'n'paste ;)
(edit: adding list style for the options)
In
moveRowAtIndexPath:toIndexPath:
add this check:
if ( fromIndexPath.section != toIndexPath.section ) return; // prevent moving to another section.
Try this
- (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)fromIndexPath toIndexPath:(NSIndexPath *)toIndexPath {
if( fromIndexPath == toIndexPath ) {
return;
}

UITableView does not go into "swipe to delete" mode

My UITableView is linked with my UIViewController instance. The UIViewController instance is the table's UITableViewDelegate and UITableViewDataSource.
Whenever a cell is swiped in the simulator, it does not trigger the "swipe to delete" mode.
I tried to provide implementations for the methods to support "swipe to delete" and table cell editing. None of them get called (none of the NSLogs are logging).
- (UITableViewCellEditingStyle)tableView:(UITableView *)tableView editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath {
NSLog(#"tableView editingStyleForRowAtIndexPath");
return UITableViewCellEditingStyleDelete;
}
- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath {
NSLog(#"tableView canEditRowAt...");
return YES;
}
- (void)tableView:(UITableView *)tableView willBeginEditingRowAtIndexPath:(NSIndexPath *)indexPath {
NSLog(#"tableView willBeginEditingRowAtIndexPath: %#", indexPath);
}
- (void)tableView:(UITableView *)tableView willEndEditingRowAtIndexPath:(NSIndexPath *)indexPath {
NSLog(#"tableView willEndEditingRowAtIndexPath: %#", indexPath);
}
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle {
NSLog(#"tableView commitEditingStyle");
}
- (void)tableView:(UITableView*)tableView didEndEditingRowAtIndexPath:(NSIndexPath *)indexPath {
NSLog(#"tableView didEndEditingRowAtIndexPath");
}
There must be a simple thing I'm forgetting, but cannot figure out what. Any ideas?
You've implemented tableView:commitEditingStyle:, but the method you need is tableView:commitEditingStyle:forRowAtIndexPath:.
That's one of the challenges with implementing protocols. If you incorrectly specify or misspell optional methods, there's no way for the compiler to know.
Here are some tips that might help in the future:
Tip 1: Cut and paste protocol method declarations directly from the documentation to avoid spelling errors and missed arguments.
Tip 2: Create sets of correct protocol methods (with mostly empty bodies) and put them in a code snippet library. Then, always use the stored snippet when adopting a protocol.

How to disable the delete button for the particular row when we are using the table view delegate method commitEditingStyle in Iphone sdk?

Here I need a help from ur side that Im using the tableview delegate method commitEditing sytle to get the delete button for every cell when we swipe.But my problem here is I dont want the delete button for the first row in the tableview and swipe should not work and I dnt have any idea how to implemet this.
Anyone's help will be much appreciated.
Thank You,
Monish.
UITableViewCell has delete style by default. To change that you need to implement tableView:editingStyleForRowAtIndexPath: method in your table view delegate. Return UITableViewCellEditingStyleNone for the 1st row and UITableViewCellEditingStyleDelete for other rows.
Edit: Sorry for incomplete answer. You also need to implement tableView:canEditRowAtIndexPath: method (something like that):
- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath{
return indexPath.row > 0;
}
Hope that'll work
- (UITableViewCellEditingStyle)tableView:(UITableView *)tableView editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath
{
if(condition check)
return UITableViewCellEditingStyleDelete;
return UITableViewCellEditingStyleNone;
}
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
{
if (editingStyle == UITableViewCellEditingStyleDelete) {
//here your code
}
}