在重新排序单元格后重新加载自定义UITableViewCell [英] Reloading custom UITableViewCell after reordering cells

查看:81
本文介绍了在重新排序单元格后重新加载自定义UITableViewCell的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有 UITableView ,它使用自定义 UITableViewCell 。单元格可以有三种类型的背景图像(在每个单元格的 .backgroundView.image 属性中设置):顶部,中间或底部。顶部和底部图像用于第一个和最后一个单元格,并且具有圆角(很像一个分组的 UITableView 的单元格)。 UITableView 中的所有其他中间单元格都有一个矩形中间背景图片。



我的问题是, UITableView 编辑模式中的单元格不会根据新位置使用不同的背景图片进行刷新。例如,如果我将第一个单元格移动到表的中间,它仍然保留其原始的顶部背景图像(带圆角),并且出现在表视图顶部的新单元格仍然具有其原始中间



我可以通过在表上执行一个 reloadData 来解决这个问题。视图,但这有一个问题,不给一个漂亮的优美的动画的变化。我注意到,当移动/拖动单元格时,在重新排序标准分组 UITableView 时,相关单元格上的背景图片发生变化(即使在移动的单元格被删除新位置),看起来很不错。我想实现相同的事情。



为此,我已经实现了 tableView:targetIndexPathForMoveFromRowAtIndexPath:toProposedIndexPath 每次在表视图中拖动一行时调用。在这里我尝试了各种方法设置 backgroundView.image 包括只是直接设置图像,然后还明确告诉它重绘单元格和/或图像使用 setNeedsLayout setNeedsDisplay ,但似乎没有使单元格重画。我有 NSLog 'ged这些更改的结果,它们似乎提交到单元格,因为正确的值出现在 NSLog ,但单元格似乎没有更新在屏幕上。



如果任何人可以指出我做错了,或建议一个更好的方法实现工作成果,我将非常感谢。谢谢!



编辑:以下代码是从赏金中提取的,并且格式化,以便更容易消化:

  UIImage * rowBackground; 
UIImage * selectionBackground;
NSInteger sectionRows = [_tableView numberOfRowsInSection:[indexPath section]];
NSInteger row = [indexPath row];
if(row == 0& row == sectionRows - 1)
{
rowBackground = [UIImage imageNamed:@field_title_bkg.png];
selectionBackground = [UIImage imageNamed:@field_title_bkg.png];
}
else if(row == 0)
{
rowBackground = [UIImage imageNamed:@table_row_top_bkg.png];
selectionBackground = [UIImage imageNamed:@table_row_top_bkg.png];
}
else if(row == sectionRows - 1)
{
rowBackground = [UIImage imageNamed:@table_bottom_row_bkg.png];
selectionBackground = [UIImage imageNamed:@table_bottom_row_bkg.png];
}
else
{
rowBackground = [UIImage imageNamed:@table_row_bkg.png];
selectionBackground = [UIImage imageNamed:@table_row_bkg.png];
}
UIImageView * rowBackGroundImageView = [[UIImageView alloc] initWithImage:rowBackground];
UIImageView * rowBackGroundSelectionImageView = [[UIImageView alloc] initWithImage:selectionBackground];
if(row!= sectionRows - 1)
{
UIImageView * sep = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@cell_separator.png]];
[sep setFrame:CGRectMake(20,56,280,1)];
[rowBackGroundImageView addSubview:sep];
}
[cell setBackgroundView:rowBackGroundImageView];
[rowBackGroundImageView release];


解决方案

在项目中写下面的代码,每个预期。

   - (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&& amp; 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&& proposed DestinationIndexPath.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;
}


I have UITableView which uses custom UITableViewCells. The cells can have one of three types of background images (set in each cell's .backgroundView.image property): top, middle, or bottom. The top and bottom images are for the first and last cells, and have rounded corners (much like a grouped UITableView's cells). All other "middle" cells within the UITableView have a rectangular middle background image.

My problem is that when reordering the cells in the UITableView's Edit mode the cells do not refresh with a different background image depending on their new location. For example, if I move the first cell into the middle of the table it still retains its original "top" background image (with rounded corners) and the new cell which appears at the top of the table view still has its original "middle" background image, which all looks a bit odd.

I can get around this by doing a reloadData on the table view, but this has the problem of not giving a nice graceful animation of the changes. I noticed that when reordering a standard grouped UITableView as soon as a cell is moved / dragged the background image on the relevant cells change (even before the moved cell has been dropped into its new location) which looks very nice. I would like to achieve the same thing.

To this end, I have implemented tableView:targetIndexPathForMoveFromRowAtIndexPath:toProposedIndexPath which is called every time a row is dragged around in the table view. Within this I have tried various methods of setting the backgroundView.image including just directly setting the image and then also explicitly telling it to redraw the cell and/or image using setNeedsLayout and setNeedsDisplay but nothing seems to make the cell redraw. I have NSLog'ged the results of these changes and they appear to be committing to the cell, as the correct values appear in the NSLog, but the cell just does not seem to be updating on screen.

If anyone could point out what I am doing wrong, or suggest a better way of achieving a working outcome, I would be very much appreciative. Thanks!

EDIT: the following code was pulled from the bounty and formatted so it can be more easily digested:

UIImage *rowBackground;
UIImage *selectionBackground;
NSInteger sectionRows = [_tableView numberOfRowsInSection:[indexPath section]];
NSInteger row = [indexPath row];
if (row == 0 && row == sectionRows - 1)
{
    rowBackground = [UIImage imageNamed:@"field_title_bkg.png"];
    selectionBackground = [UIImage imageNamed:@"field_title_bkg.png"];
}
else if (row == 0)
{
    rowBackground = [UIImage imageNamed:@"table_row_top_bkg.png"];
    selectionBackground = [UIImage imageNamed:@"table_row_top_bkg.png"];
}
else if (row == sectionRows - 1)
{
    rowBackground = [UIImage imageNamed:@"table_bottom_row_bkg.png"];
    selectionBackground = [UIImage imageNamed:@"table_bottom_row_bkg.png"];
}
else
{
    rowBackground = [UIImage imageNamed:@"table_row_bkg.png"];
    selectionBackground = [UIImage imageNamed:@"table_row_bkg.png"];
}
UIImageView *rowBackGroundImageView = [[UIImageView alloc] initWithImage:rowBackground];
UIImageView *rowBackGroundSelectionImageView = [[UIImageView alloc] initWithImage:selectionBackground];
if (row != sectionRows - 1)
{
    UIImageView *sep = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"cell_separator.png"]];
    [sep setFrame:CGRectMake(20, 56, 280, 1)];
    [rowBackGroundImageView addSubview:sep];
}
[cell setBackgroundView:rowBackGroundImageView];
[rowBackGroundImageView release];

解决方案

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;
}

这篇关于在重新排序单元格后重新加载自定义UITableViewCell的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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