Reloading custom UITableViewCell after reordering cells

后端 未结 6 1417
忘了有多久
忘了有多久 2021-02-15 16:04

I have UITableView which uses custom UITableViewCells. The cells can have one of three types of background images (set in each cell\'s .backgrou

相关标签:
6条回答
  • 2021-02-15 16:41

    (this solution only works for the reordering of rows within the same section. It'll fail when dragging and dropping rows to a different section)

    I had the same problem when updating a cell's detail label text after being reordered.

    I solved it with the following code:

    - (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)fromIndexPath  toIndexPath:(NSIndexPath *)toIndexPath 
    {
    UITableViewCell* cell = [self.table cellForRowAtIndexPath:fromIndexPath]; 
    cell.detailTextLabel.text = @"NEW STRING";
    }
    

    Note that you have to update the cell at fromIndexPath, because it seems that the internal state of the tableview doesn't update until this method returns. If you get the cell at toIndexPath, after reordering finishes, you will see the neighbor cell gets updated. (either top or bottom one).

    0 讨论(0)
  • 2021-02-15 16:43

    Write below code in your project and it should work as per expectations.

    - (NSIndexPath *)tableView:(UITableView *)tableView
    targetIndexPathForMoveFromRowAtIndexPath:(NSIndexPath *)sourceIndexPath
          toProposedIndexPath:(NSIndexPath *)proposedDestinationIndexPath
    {
        NSInteger sectionRows = [tableView numberOfRowsInSection:[sourceIndexPath section]];
    
        UITableViewCell *sourceCell = [tableView cellForRowAtIndexPath:sourceIndexPath];
        UITableViewCell *destCell = [tableView cellForRowAtIndexPath:proposedDestinationIndexPath];
    
        if(sourceIndexPath.row == 0 && proposedDestinationIndexPath.row == 1)
        {
            ((UIImageView *)destCell.backgroundView).image = [UIImage imageNamed:@"table_row_top_bkg.png"];
    
            if(proposedDestinationIndexPath.row == sectionRows - 1)
                ((UIImageView *)sourceCell.backgroundView).image = [UIImage imageNamed:@"table_bottom_row_bkg.png"];
            else
                ((UIImageView *)sourceCell.backgroundView).image = [UIImage imageNamed:@"table_row_bkg.png"];
        }
    
        else if(sourceIndexPath.row == sectionRows - 1 && proposedDestinationIndexPath.row == sectionRows - 2)
        {
            ((UIImageView *)destCell.backgroundView).image = [UIImage imageNamed:@"table_bottom_row_bkg.png"];
    
            if(proposedDestinationIndexPath.row == 0)
                ((UIImageView *)sourceCell.backgroundView).image = [UIImage imageNamed:@"table_row_top_bkg.png"];
            else
                ((UIImageView *)sourceCell.backgroundView).image = [UIImage imageNamed:@"table_row_bkg.png"];
        }
    
        else if(proposedDestinationIndexPath.row == 0)
        {
            ((UIImageView *)sourceCell.backgroundView).image = [UIImage imageNamed:@"table_row_top_bkg.png"];
    
            destCell = [tableView cellForRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:proposedDestinationIndexPath.section]];
            if(sectionRows == 2)
                ((UIImageView *)destCell.backgroundView).image = [UIImage imageNamed:@"table_bottom_row_bkg.png"];
            else
                ((UIImageView *)destCell.backgroundView).image = [UIImage imageNamed:@"table_row_bkg.png"];
        }
    
        else if(proposedDestinationIndexPath.row == sectionRows - 1)
        {
            ((UIImageView *)sourceCell.backgroundView).image = [UIImage imageNamed:@"table_bottom_row_bkg.png"];
    
            destCell = [tableView cellForRowAtIndexPath:[NSIndexPath indexPathForRow:sectionRows - 1 inSection:proposedDestinationIndexPath.section]];
            if(sectionRows == 2)
                ((UIImageView *)destCell.backgroundView).image = [UIImage imageNamed:@"table_row_top_bkg.png"];
            else
                ((UIImageView *)destCell.backgroundView).image = [UIImage imageNamed:@"table_row_bkg.png"];
        }
    
        return proposedDestinationIndexPath;
    }
    
    0 讨论(0)
  • 2021-02-15 16:45

    the apis for partially reloading rows in the ios sdk doesn't function well (that's why ppl follow this post here)

    I end up using timer to reload the whole data after reordering animation finishes. It works for me.

    - (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)fromIndexPath toIndexPath:(NSIndexPath *)toIndexPath 
    {
        //things to be done when reordering rows
        ....
    
    
        //issue a timer to reload data
        NSTimer* timer = [NSTimer scheduledTimerWithTimeInterval: 0.1
                                                 target: self
                                               selector:@selector(updateRow)
                                               userInfo: nil repeats:NO];
    
    
    }
    
    
    -(void) updateRow
    {
    
        [self.table reloadData];
    
    }
    
    0 讨论(0)
  • 2021-02-15 16:47

    If you just want to reload a few cells rather the entire table you can use:

    reloadRowsAtIndexPaths:withRowAnimation:
    

    available as an instance method of UITableView.

    0 讨论(0)
  • 2021-02-15 17:00

    Try this:

    [tableView beginUpdates];
    [tableView endUpdates];
    
    0 讨论(0)
  • 2021-02-15 17:02

    I haven't tried myself but why not test your indexPath.row value on the cellForRowAtIndexPath method and provide the different backgroundView.image values for first and last row?

    - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    

    I hope this helps. Cheers, Rog

    0 讨论(0)
提交回复
热议问题