我UITableView
使用自定义UITableViewCell
。单元格可以具有三种类型的背景图像之一(在每个单元格的.backgroundView.image
属性中设置):顶部,中间或底部。顶部和底部图像用于第一个和最后一个单元格,并且具有圆角(非常类似于分组的UITableView
个单元格)。 UITableView
中的所有其他“中间”单元格都具有矩形中间背景图像。
我的问题是,在UITableView
的编辑模式下重新排序单元格时,单元格不会根据新位置刷新不同的背景图像。例如,如果我将第一个单元格移动到表格的中间,它仍然保留其原始的“顶部”背景图像(带有圆角),并且出现在表格视图顶部的新单元格仍然具有其原始“中间”背景图片,这看起来有点奇怪。
我可以通过在表视图上执行reloadData
来解决这个问题,但这样做的问题是不能给出更改的优美动画。我注意到,当移动/拖动单元格时重新排序标准分组UITableView
时,相关单元格上的背景图像会发生变化(甚至在移动的单元格被放入其新位置之前),这看起来非常好。我想达到同样的目的。
为此,我实现了tableView:targetIndexPathForMoveFromRowAtIndexPath:toProposedIndexPath
,每次在表视图中拖动一行时都会调用它。在此我尝试了各种设置backgroundView.image
的方法,包括直接设置图像,然后明确告诉它使用setNeedsLayout
和setNeedsDisplay
重绘单元格和/或图像但似乎没有使细胞重绘。我NSLog
'对这些更改的结果进行了调整,它们似乎正在提交到单元格,因为正确的值出现在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];
答案 0 :(得分:4)
在项目中写下以下代码,它应该按照预期工作。
- (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;
}
答案 1 :(得分:1)
如果您只想重新加载几个单元格而不是整个表格,您可以使用:
reloadRowsAtIndexPaths:withRowAnimation:
可用作UITableView的实例方法。
答案 2 :(得分:1)
试试这个:
[tableView beginUpdates];
[tableView endUpdates];
答案 3 :(得分:0)
我没有尝试过,但为什么不在cellForRowAtIndexPath方法上测试indexPath.row值并为第一行和最后一行提供不同的backgroundView.image值?
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
我希望这会有所帮助。 干杯, ROG
答案 4 :(得分:0)
<强> (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)
强>
在重新排序后更新单元格的详细信息标签文本时遇到了同样的问题。
我用以下代码解决了它:
- (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)fromIndexPath toIndexPath:(NSIndexPath *)toIndexPath
{
UITableViewCell* cell = [self.table cellForRowAtIndexPath:fromIndexPath];
cell.detailTextLabel.text = @"NEW STRING";
}
请注意,您必须更新 fromIndexPath
处的单元格,因为在此方法返回之前,似乎表格视图的内部状态不会更新。如果您在toIndexPath
获取单元格,则在重新排序完成后,您将看到相邻单元格已更新。 (无论是顶部还是底部)。
答案 5 :(得分:0)
在ios sdk中部分重新加载行的api运行不正常(这就是为什么ppl在这里关注这篇文章)
在重新排序动画结束后,我最终使用计时器重新加载整个数据。 它对我有用。
- (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];
}