UITableview 单元格保留自定义图像视图过滤器

Posted

技术标签:

【中文标题】UITableview 单元格保留自定义图像视图过滤器【英文标题】:UITableview cell retain custom image view filter 【发布时间】:2015-04-22 15:01:35 【问题描述】:

我在开发 tableview 自定义单元格时经常遇到这个问题。

这是一个问题,我有一个 tableview,它有很多自定义单元格(一个 UIImageView 和 UILabel)当用户点击这个单元格中的任何一个会推送新的 UIViewController 并且用户填充一些数据并点击“保存”viewcontroller 用委托推回方法。

在此委托方法中,我检查点击的单元格并更改该色调颜色(如选定状态,但我只是更改自定义 imageview 色调颜色)。所以这会正确改变,但是当我滚动任何垂直方向时,色调颜色会消失。下面的图片和代码用于正确计算。

当从委托方法弹出视图控制器时(正常工作)

垂直方向滚动时可以

// Custom cell

@interface CustomCell : UITableViewCell
@property(strong, nonatomic) UIImageView *imageView;
@property(strong, nonatomic) UILabel *titleLabel;
@end

// Custom Cell implementation nothing special here.

// UIViewController delegate method when pop back
// I'm filling specific color 

@interface UIViewController
@property (strong,nonatomic) CustomCell *myCustomCell;
@end

@implementation UIViewController



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

    _myCustomCell = (CustomCell *)[self.tableView dequeueReusableCellWithIdentifier:@"CustomCell" forIndexPath:indexPath];

    ...


- (void)userTappedBackButton 
    _myCustomCell.imageView.image = [cell.customImageView.image imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate];
    _myCustomCell.imageView.tintColor = [UIColor colorWithRed:0.27 green:0.58 blue:0.98 alpha:1];

@end

【问题讨论】:

【参考方案1】:

您遇到的问题是您正在保存对 UITableViewCell 的引用,但单元格正在被重用。

您需要以另一种方式保存有关要突出显示的单元格的信息,该方式不受正在重复使用的单元格的影响。我建议使用indexPath

类似下面的东西应该可以工作:

@property (nonatomic, strong) NSIndexPath *lastSelectedIndexPath;


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

    CustomCell *cell = (CustomCell *)[self.tableView dequeueReusableCellWithIdentifier:@"CustomCell" forIndexPath:indexPath];
    if([indexPath isEqual:self.lastSelectedIndexPath]) 
        cell.imageView.image = [cell.customImageView.image imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate];
        cell.imageView.tintColor = [UIColor colorWithRed:0.27 green:0.58 blue:0.98 alpha:1];
    
    ...


-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath 
    // Save the selected indexPath
    self.selectedIndexPath =  indexPath;

- (void)userTappedBackButton 
    // Reload the row that needs to be updated with the new tint color
    [tableView reloadRowsAtIndexPaths:@[self.selectedIndexPath] withRowAnimation:UITableViewRowAnimationAutomatic];

如果成功了请告诉我。

【讨论】:

我有不止一个部分,所以我猜这段代码行不通。 您正在保存同时具有节和行信息的 indexPath,因此它肯定会与更多节一起使用【参考方案2】:

在选中时跟踪被点击的单元格的索引路径,而不是在滚动时重复使用的单元格本身。当您为匹配的“选定”索引路径呈现单元格时,以及返回视图时,应用 cellForRow 中的选定样式

更新:添加代码以澄清

在您的自定义单元格中,提供启用/禁用色调的简单方法:

@interface CustomCell : UITableViewCell

@property(strong, nonatomic) UIImageView *imageView;
@property(strong, nonatomic) UILabel *titleLabel;

- (void)enableLastSelectedHighlight;
- (void)disableLastSelectedHighlight;

@end

实施:

@implementation CustomCell

- (void)prepareForReuse

    [super prepareForReuse];

    // Reset prior to being reused
    [self disableLastSelectedHighlight];


- (void)enableLastSelectedHighlight

    self.imageView.image = [cell.customImageView.image imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate];
    self.imageView.tintColor = [UIColor colorWithRed:0.27 green:0.58 blue:0.98 alpha:1];


- (void)disableLastSelectedHighlight;

    self.imageView.image = [cell.customImageView.image imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];


@end

在您的 TableViewController.m 文件中,通过didSelectRowAtIndexPath 或您现有的自定义委托userTappedBackButton 跟踪选择。的实现将是相同的:

@interface MyTableViewController ()

@property (nonatomic, strong) NSIndexPath *lastSelectedCellIndexPath;

@end

@implementation MyTableViewController

// Your existing implementation
// ...

-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath

    // Update our reference to the tinted row
    [self setLastSelectedCellIndexPath:indexPath];

    // Un-tint any currently tinted cells
    [self.tableView.visibleCells makeObjectsPerformSelector:@selector(disableLastSelectedHighlight)];


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

    // Get your cell
    CustomCell *cell = (CustomCell *)[self.tableView dequeueReusableCellWithIdentifier:@"CustomCell" forIndexPath:indexPath];
    if (indexPath == self.lastSelectedCellIndexPath) 
        // This cell should be tinted
        [cell enableLastSelectedHighlight];
    
    // The rest of your cell setup...


@end

【讨论】:

谢谢老兄。这就是我需要的。但另一种方法是所有单元的延迟加载。但有时它会带来麻烦。 我很想知道为什么,以及你最终得到什么解决方案 当我一次又一次点击同一个单元格时,我的数组变成了这样 我认为这不是为了应用程序性能而“方便” . 添加了代码示例以使其更清晰。听起来您将它存储为一个数组 - 除非多个将被着色,否则不需要。然后,您可以在重新添加之前检查索引路径是否已经是“着色索引路径”数组的成员。或者我们的 NSSet。

以上是关于UITableview 单元格保留自定义图像视图过滤器的主要内容,如果未能解决你的问题,请参考以下文章

如何在自定义单元格的 initWithStyle: 方法中获取 UITableView 的宽高?

UITableView 中的自定义单元格使图像在滚动时重叠

从自定义单元格访问父视图

自定义 UITableView - iphone

分组 UITableView 自定义绘制单元格,而不更改背景颜色?

UITableview单元格图像中的uiimageview中的UIButton没有改变