如何在用户重新布置单元格时刷新UITableView? [英] How can I refresh a UITableView while a user is re-arranging cells?

查看:85
本文介绍了如何在用户重新布置单元格时刷新UITableView?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个可编辑的UITableView。当我的用户重新安排单元格,我想能够更新tableview,因为我得到一个有趣的情况,当我重新安排底部单元格,并将其插入中间。它创建一个不想要的效果,因为底部行是圆的,中间的行不应该。如何防止这种情况发生?

I have an editable UITableView. While my user is re-arranging the cells, I want to be able to update the tableview because I get a funny situation when I re-arrange the bottom cell and insert it into the middle. It create an unwanted effect because the bottom row is rounded and the middle row should not be. How can I prevent this from happening?

为了实现这个效果,我必须设置每个 UITableViewCell的 backgroundView

To achieve this look I had to set the backgroundView of each UITableViewCell. The top and bottom ones are using a separate image than ones in the middle.

UPDATED

我不确定是否缺少任何情况,因为重新排序时图片仍然会乱七八糟。

I am not sure if I am missing any cases, because the images still get messed up when re-ordering.

for (NSIndexPath* visibleIndexPath in tableView.indexPathsForVisibleRows) {
        UITableViewCell* cell = [tableView cellForRowAtIndexPath:visibleIndexPath];

        //Top moving to middle rows
        if (sourceIndexPath.row == 0 && proposedDestinationIndexPath.row != sectionRows - 1) {
            ((UIImageView *)cell.backgroundView).image = [UIImage imageNamed:@"tablemiddle55@2x.png"];
        }
        //Top moving to bottom
        else if (sourceIndexPath.row == 0 && proposedDestinationIndexPath.row == sectionRows - 1) {
            ((UIImageView *)cell.backgroundView).image = [UIImage imageNamed:@"tablebottom55@2x.png"];
        }
        //Top moving to top
        else if (sourceIndexPath.row == 0 && proposedDestinationIndexPath.row == 0) {
            ((UIImageView *)cell.backgroundView).image = [UIImage imageNamed:@"tabletop55@2x.png"];
        }
        //Middle moving to top
        else if (sourceIndexPath.row != 0 && sourceIndexPath.row != sectionRows -1 && proposedDestinationIndexPath.row == 0)
        {
            ((UIImageView *)cell.backgroundView).image = [UIImage imageNamed:@"tabletop55@2x.png"];
        }
        //Middle moving to bottom
        else if (sourceIndexPath.row != 0 && sourceIndexPath.row != sectionRows -1 && proposedDestinationIndexPath.row == sectionRows - 1)
        {
            ((UIImageView *)cell.backgroundView).image = [UIImage imageNamed:@"tablebottom55@2x.png"];
        }
        //Middle moving to middle
        else if (sourceIndexPath.row != 0 && sourceIndexPath.row != sectionRows -1 && 
                 proposedDestinationIndexPath.row != sectionRows -1 && proposedDestinationIndexPath.row !=0)
        {
            ((UIImageView *)cell.backgroundView).image = [UIImage imageNamed:@"tablemiddle55@2x.png"];
        }
        //Bottom moving to top
        else if (sourceIndexPath.row == sectionRows - 1 && proposedDestinationIndexPath.row == 0)
        {
            ((UIImageView *)cell.backgroundView).image = [UIImage imageNamed:@"tabletop@2x.png"];
        }
        //Bottom moving to middle
        else if (sourceIndexPath.row == sectionRows - 1 && proposedDestinationIndexPath.row != 0 && proposedDestinationIndexPath.row != sectionRows - 1)
        {
            ((UIImageView *)cell.backgroundView).image = [UIImage imageNamed:@"tablemiddle@2x.png"];
        }
        //Bottom moving to bottom
        else if (sourceIndexPath.row == sectionRows - 1 && proposedDestinationIndexPath.row == sectionRows - 1)
        {
            ((UIImageView *)cell.backgroundView).image = [UIImage imageNamed:@"tablebottom@2x.png"];
        }
    }


推荐答案

你发布的代码大多是错误的,因为 for {} 。因为它现在,你做的事情,如如果目的地是这样的源,这样,修改所有当前可见的单元格。但是无论如何,这不是主要的问题。

The code you posted is mostly wrong because of the for {}. As it stands right now, you do something like "if the destination is such and the source is such, modify all the currently visible cells". But anyway, this is not the main problem.

我必须说,我玩了很多时间与方法 tableView:targetIndexPathForMoveFromRowAtIndexPath: toProposedIndexPath:,甚至尝试回答这个问题。

I must say, I've played a lot of time with the method tableView:targetIndexPathForMoveFromRowAtIndexPath:toProposedIndexPath: before even attempting to answer this question. Now I feel more confident to write it.

对于初学者,使用此方法结合 tableView:cellForRowAtIndexPath:如果你不知道发生了什么,不是一个好的选择。简单地说,即使单元格已经为动画移动,在用户停止拖动单元格之前,更改并不会真正影响tableView。

For starters, using this method in conjunction with tableView:cellForRowAtIndexPath: is not a good choice if you don't know what's happening. Simply put, even though the cells have shifted for the animation, the changes don't really affect the tableView until the user stops dragging the cell.

例如,假设您的索引为0的单元格的标题为 @Hello,下一个单元格为 @ ,如果您开始向下拖动第一个单元格,动画将单元格Hello向上移动一行,但调用 tableView:cellForRowAtIndexPath 索引为0的行总是返回Hello单元格。 tableView在tableView重新排序结束之前不受影响,其他一切都只是眼睛一样。

For example, let's say that you have the cell at index 0 with the title @"Hello", and the next cell with @"World", if you start dragging the first cell downwards, the animation will move the cell "Hello" one row upwards, but calling tableView:cellForRowAtIndexPath for the row at index 0 will always return the "Hello" cell. The tableView is unaffected until the tableView reorder ends, everything else is just eye-candy.

因此,为了回答你的问题,很快当用户移动单元格),你应该做以下,例如,第一行:

So, to answer your question, and to swap the images on the fly (as soon as the user moves the cell), you should do the following, for example, for the first row:

//Top moving to middle rows
if (sourceIndexPath.row == 0 && proposedDestinationIndexPath.row != 0)
{
    UITableViewCell *cell = [tableView cellForRowAtIndexPath:[NSIndexPath indexPathForRow:1 inSection:sourceIndexPath.section]];
    ((UIImageView *)cell.backgroundView).image = [UIImage imageNamed:@"tablemiddle55"];
}

用户向下拖动第0行,将其背景交换到顶部,因为他将成为新的顶行。对于底行或中间行成为第一行,必须考虑类似的情况。此外,在这种情况下,不带有可见单元格的 for {}

One the user drags the row 0 downwards, it tells the row at 1 to swap its background to the top, as he will become the new top row. Similar cases must be considered for the bottom row, or middle row becoming the first one. Also, the for {} with the visible cells is not necessary in this case.

好吧,我设法使所有的情况,它有一些奇怪的事情在这里和那里,但它的大部分时间。这里的代码只是将detailLabel更改为First/Middle/Last,但是应该很容易用Find& Replace替换。

Okay, I managed to make ALL the cases, it has some weird things here and there, but it works most of the time. The code here just changes the detailLabel to "First"/"Middle"/"Last", but that should be easy to change with a Find&Replace.

- (NSIndexPath *)tableView:(UITableView *)tableView targetIndexPathForMoveFromRowAtIndexPath:(NSIndexPath *)sourceIndexPath toProposedIndexPath:(NSIndexPath *)proposedDestinationIndexPath
{
    //NSLog(@"%d -> %d (proposed)", sourceIndexPath.row, proposedDestinationIndexPath.row);

    NSInteger lastRow = [arrayWithContent count]-1;

    // Adjust the row being moved
    if (proposedDestinationIndexPath.row == 0)
        [tableView cellForRowAtIndexPath:sourceIndexPath].detailTextLabel.text = @"First";
    else if (proposedDestinationIndexPath.row == lastRow)
        [tableView cellForRowAtIndexPath:sourceIndexPath].detailTextLabel.text = @"Last";
    else
        [tableView cellForRowAtIndexPath:sourceIndexPath].detailTextLabel.text = @"Middle";

    // Top -> Middle
    if (sourceIndexPath.row == 0 && proposedDestinationIndexPath.row == 1)
    {
        NSLog(@"Top -> Middle");
        [tableView cellForRowAtIndexPath:[NSIndexPath indexPathForRow:1 inSection:0]].detailTextLabel.text = @"First";
    }
    // Top -> Top (user is screwing around)
    else if (sourceIndexPath.row == 0 && proposedDestinationIndexPath.row == 0)
    {
        NSLog(@"Top -> Top");
        [tableView cellForRowAtIndexPath:[NSIndexPath indexPathForRow:1 inSection:0]].detailTextLabel.text = @"Middle";
    }
    // Middle -> Top
    else if (sourceIndexPath.row > 0 && proposedDestinationIndexPath.row == 0)
    {
        NSLog(@"Middle -> Top");
        [tableView cellForRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:0]].detailTextLabel.text = @"Middle";
    }
    // Middle -> Bottom
    else if (sourceIndexPath.row < lastRow && proposedDestinationIndexPath.row == lastRow)
    {
        NSLog(@"Middle -> Bottom");
        [tableView cellForRowAtIndexPath:[NSIndexPath indexPathForRow:lastRow inSection:0]].detailTextLabel.text = @"Middle";
    }
    // Bottom -> Middle
    else if (sourceIndexPath.row == lastRow && proposedDestinationIndexPath.row == lastRow-1)
    {
        NSLog(@"Bottom -> Middle");
        [tableView cellForRowAtIndexPath:[NSIndexPath indexPathForRow:(lastRow-1) inSection:0]].detailTextLabel.text = @"Last";
    }
    // Bottom -> Bottom (user is screwing around, AGAIN)
    else if (sourceIndexPath.row == lastRow && proposedDestinationIndexPath.row == lastRow)
    {
        NSLog(@"Bottom -> Bottom");
        [tableView cellForRowAtIndexPath:[NSIndexPath indexPathForRow:(lastRow-1) inSection:0]].detailTextLabel.text = @"Middle";
    }
    // Middle -> Top -> Middle (ugh)
    else if (sourceIndexPath.row > 0 && sourceIndexPath.row < lastRow && proposedDestinationIndexPath.row == 1)
    {
        NSLog(@"Middle -> Top -> Middle");
        [tableView cellForRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:0]].detailTextLabel.text = @"First";
    }
    // Middle -> Bottom -> Middle (ugh x2)
    else if (sourceIndexPath.row > 0 && sourceIndexPath.row < lastRow && proposedDestinationIndexPath.row == lastRow-1)
    {
        NSLog(@"Middle -> Bottom -> Middle");
        [tableView cellForRowAtIndexPath:[NSIndexPath indexPathForRow:lastRow inSection:0]].detailTextLabel.text = @"Last";
    }

    return proposedDestinationIndexPath;
}

这篇关于如何在用户重新布置单元格时刷新UITableView?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆