【问题标题】:UITableview cell retain custom image view filterUITableview 单元格保留自定义图像视图过滤器
【发布时间】: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

【问题讨论】:

    标签: ios objective-c iphone uitableview custom-cell


    【解决方案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。
    猜你喜欢
    • 2012-12-06
    • 1970-01-01
    • 1970-01-01
    • 2023-03-24
    • 1970-01-01
    • 2018-08-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多