开发者

Enabling edit mode for only one row in table view

开发者 https://www.devze.com 2022-12-22 15:40 出处:网络
I can set the edit mode for a while uitableview by ca开发者_运维问答lling [tableView setEditing:YES]; But that sets the edit mode for all the rows in a table.

I can set the edit mode for a while uitableview by ca开发者_运维问答lling [tableView setEditing:YES]; But that sets the edit mode for all the rows in a table.

Is there a way to detect what row was swiped an enable the edit mode only for that row?

Thanks


I haven't coded this up, but here's the idea.

Create selectionIndexPath in .h

NSIndexPath *selectionIndexPath;

Then in .m

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath

save indexPath to selectionIndexPath and call:

[self.tableView setEditing:YES];

Then in:

- (UITableViewCellEditingStyle)tableView:(UITableView *)tableView editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath

if (selectionPath.row == indexPath.row)
    {
        return UITableViewCellEditingStyleDelete;
    }
    else
    {
        return UITableViewCellEditingStyleNone;     
    }
}

You could also catch the touches and then do more or less the same thing. Something like this...

NSSet *touches = [event allTouches];
UITouch *touch = [touches anyObject];
CGPoint currentTouchPosition = [touch locationInView:self.tableView];
NSIndexPath *indexPath = [self.tableView indexPathForRowAtPoint: currentTouchPosition];
if (indexPath != nil)
{
        // save indexPath and setEditing Mode here
}

Didn't have any time to code it up, but that's the main idea.


Implement the editingStyleForRowAtIndexPath method:

- (UITableViewCellEditingStyle)tableView:(UITableView *)tableView editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath
{
    if (indexPath.row == 3)
    {
        return UITableViewCellEditingStyleDelete;
    }
    else
    {
        return UITableViewCellEditingStyleNone;     
    }
}

//
//
EDIT: As you clarified in your comments, you want to let the user swipe on a cell and then either delete or move the cell.

I believe to let the user do both, the table (not just the cell) has to be placed in editing mode and if you do this only when the user swipes the cell, there will be an annoying flicker as the table redraws itself to make space for the insert/delete buttons. Jordan has provided sample code to do this.

The alternate as suggested by Ian Henry is to implement swipe-to-delete. However, there doesn't appear to be a swipe-to-move equivalent. To implement swipe-to-delete, do the following:

  • keep table editing turned OFF
  • implement editingStyleForRowAtIndexPath and just return UITableViewCellEditingStyleDelete regardless of indexpath
  • implement willBeginEditingRowAtIndexPath but do nothing in it
  • implement commitEditingStyle and in it delete row from your data source and call deleteRowsAtIndexPaths

Now when user swipes a cell, a Delete button will appear on the right. If user taps that, commitEditingStyle will be called and if user taps anything else, Delete will be canceled.


There is a method -setEditing:animated: for UITableViewCell also. So if you override it in a custom UITableViewCell and send the message to super only if it is editable, you can achieve what you want.

To be more clear. Subclass UITableViewCell and maintain a bool in it, say:

@interface CustomTableViewCell : UITableViewCell 
{
    BOOL cellEditable;
}
@property (readwrite, assign) BOOL cellEditable;

@end

Next, in your tableview delegate method, return an object of CustomTabeViewCell with the cellEditable property appropriately set for the row (whether that row is editable or not).

-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    CustomTableViewCell *newCell = [[CustomTableViewCell alloc] init];
    if (row_is_editable)
        [newCell setCellEditable:YES];
    else
        [newCell setCellEditable:NO];
    return [newCell autorelease];
}

According to the documentation of UITableViewCell's - (void)setEditing:(BOOL)editing animated:(BOOL)animated method -

"When you call this method with the value of editing set to YES, and the UITableViewCell object is configured to have controls, the cell shows an insertion (green plus) or deletion control (red minus) on the left side of each cell and a reordering control on the right side. This method is called on each visible cell when the setEditing:animated: method of UITableView is invoked. Calling this method with editing set to NO removes the controls from the cell."

So all we need to do is override the -setEditing:animated: method in our CustomTableViewCell and perform this:

-(void)setEditing:(BOOL)editing animated:(BOOL)animated
{
    if ([self cellEditable])
    {
        [super setEditing:editing
                 animated:animated];
    }
    else
    {
        [super setEditing:NO 
                 animated:NO];
    }
}

And you are done, now when you trigger -setEditing:animated: on your table view, only the rows whose cells you set as cellEditable will be editable.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号