Using insert rows in a UITableView

大城市里の小女人 提交于 2019-12-17 17:27:10

问题


I'd like my UITableView to behave like the the table in the Contacts editor, i.e. the user should hit Edit and an "add new category" row should appear at the bottom of each section.

I'm using the below code to do this, but the problem is that there is no smooth transition as there is in Contacts. Instead, the new row suddenly appears. How can I get the animation?

Also, how do I respond to clicks on the "add new category" row? The row is not clickable in my current implementation.

Do I need to reload the data when the user starts editing? I am doing this because otherwise the insertion rows are never drawn.

Thanks.

- (void)setEditing:(BOOL)editing animated:(BOOL)animated {
    [super setEditing:editing animated:animated];
    [self.tableView setEditing:editing animated:animated];
    [tableView reloadData];
}

- (NSInteger)tableView:(UITableView *)_tableView numberOfRowsInSection:(NSInteger)section {
    // ...
    if( self.tableView.editing ) 
        return 1 + rowCount;
}

- (UITableViewCell *)tableView:(UITableView *)_tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    // .....
    NSArray* items = ...;
    if( indexPath.row >= [items count] ) {
        cell.textLabel.text = @"add new category";
    }
    // ...

    return cell;
}

- (UITableViewCellEditingStyle)tableView:(UITableView *)tableView editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath {
    NSArray* items = ...;

    if( indexPath.row == [items count] )
        return UITableViewCellEditingStyleInsert;

    return UITableViewCellEditingStyleDelete;
}

回答1:


I was missing one thing. In setEditing:, instead of calling reloadData I should have done:

- (void)setEditing:(BOOL)editing animated:(BOOL)animated {
    [super setEditing:editing animated:animated];
    [self.tableView setEditing:editing animated:animated]; // not needed if super is a UITableViewController

    NSMutableArray* paths = [[NSMutableArray alloc] init];

    // fill paths of insertion rows here

    if( editing )
        [self.tableView insertRowsAtIndexPaths:paths withRowAnimation:UITableViewRowAnimationBottom];
    else
        [self.tableView deleteRowsAtIndexPaths:paths withRowAnimation:UITableViewRowAnimationBottom];

    [paths release];
}



回答2:


Responding to clicks on the row might be done in the didSelectRowAtIndexPath method, for indexPath.row == [items count]. For the animation, I suggest taking a look here, at the insertRowsAtIndexPaths:withRowAnimation: method. There's a post on how to use it here.




回答3:


An unwanted side effect of the highlighted solution is that the "add" row is inserted also when the user just swipes one single row (provided that swiping is enabled). The following code solves this dilemma:

// Assuming swipeMode is a BOOL property in the class extension.

- (void)tableView:(UITableView *)tableView willBeginEditingRowAtIndexPath:(NSIndexPath *)indexPath
{
    // Invoked only when swiping, not when pressing the Edit button.
    self.swipeMode = YES;
}

- (void)tableView:(UITableView *)tableView didEndEditingRowAtIndexPath:(NSIndexPath *)indexPath
{
    self.swipeMode = NO;
}

Your code would require a small change:

- (void)setEditing:(BOOL)editing animated:(BOOL)animated {
    [super setEditing:editing animated:animated];
    [self.tableView setEditing:editing animated:animated]; // not needed if super is a UITableViewController

    if (!self.swipeMode) {

        NSMutableArray* paths = [[NSMutableArray alloc] init];

        // fill paths of insertion rows here

        if( editing )
            [self.tableView insertRowsAtIndexPaths:paths withRowAnimation:UITableViewRowAnimationBottom];
        else
            [self.tableView deleteRowsAtIndexPaths:paths withRowAnimation:UITableViewRowAnimationBottom];
        [paths release];
    }
}


来源:https://stackoverflow.com/questions/1470898/using-insert-rows-in-a-uitableview

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!