自定义 UITableViewCell 未更新

Posted

技术标签:

【中文标题】自定义 UITableViewCell 未更新【英文标题】:Custom UITableViewCell not updating 【发布时间】:2014-07-13 10:27:16 【问题描述】:

所以基本上我有一个自定义 UITableViewCell(在这种情况下是一个简单的单元格,中间设置了 UIImageView),它被正确子类化了(我有一个单元格的 .h .m 文件,并且图像视图被正确地“输出”了)。

在加载单元格时,我需要能够将 UIImageView 更改为圆形并向 UIImageView 添加手势识别器(这样如果用户点击 ImageView,它将加载 UIImagePicker - 允许用户设置图像)。

我面临的问题是,尽管代码是根据调试器执行的,但 UI 从未更新 - (我仍然看到一个通用的方形 UIImageView 并且手势识别器不起作用)。

下面是 cellforrowatindexpath 委托方法的代码:

-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 
    if (indexPath.row==0 && indexPath.section==0) 
        static NSString *CellIdentifier = @"Profile Cell";
        Profileviewcell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
        if (cell == nil) 
            cell = [[Profileviewcell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
        
        cell.ProfileImage.layer.cornerRadius = cell.ProfileImage.bounds.size.width/2;
        cell.ProfileImage.layer.masksToBounds = YES;
        [cell.ProfileImage setUserInteractionEnabled:YES];
        UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(LoadImage:)];
        tap.cancelsTouchesInView = YES;
        tap.numberOfTapsRequired = 1;
        tap.delegate = self;
        [cell.ProfileImage addGestureRecognizer:tap];
        [cell setNeedsDisplay];
        return cell;
     else 
        //return a standard cell 
    

我也尝试在 willdisplaycell 委托方法中放入相同的代码(以及 [cell setNeedsdisplay] 但这也不起作用。

- (void) tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath

    if (indexPath.row==0 && indexPath.section==0) 
        Profileviewcell *cell = [self.tableView cellForRowAtIndexPath:indexPath];
        cell.ProfileImage.layer.cornerRadius = cell.ProfileImage.bounds.size.width/2;
        cell.ProfileImage.layer.masksToBounds = YES;
        [cell.ProfileImage setUserInteractionEnabled:YES];
        UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(LoadImage:)];
        tap.cancelsTouchesInView = YES;
        tap.numberOfTapsRequired = 1;
        tap.delegate = self;
        [cell.ProfileImage addGestureRecognizer:tap];
        [cell setNeedsDisplay];
    


Initwithstyle 代码:

- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier

    self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
    if (self) 
        self.ProfileImage = [[UIImageView alloc] initWithFrame:CGRectMake(110,5,100,100)];
        [self.ProfileImage setImage:[UIImage imageNamed:@"General Profile"]];
        self.ProfileImage.layer.cornerRadius = self.ProfileImage.bounds.size.width/2;
        self.ProfileImage.layer.masksToBounds = YES;
        [self.ProfileImage setUserInteractionEnabled:YES];
        [self.contentView addSubview:self.ProfileImage];
    
    return self;

关于为什么单元格 UI 永远不会更新的任何想法?我已经检查了 Stack Overflow 是否存在类似问题,并且提供的每个解决方案似乎都不适合我。抱歉,如果这是一个简单的问题 - 我最近才开始 ios 开发。

非常感谢!

【问题讨论】:

修改layer并添加手势识别器时cell.ProfileImage是否等于nil?如果是这样,那将说明您遇到的问题。 @bobnoble 非常感谢您的回复!是的,根据调试器它为零,但我不完全确定为什么!该单元格是情节提要中的原型单元格,我也在 Xcode 中创建了 UITableViewCell 的子类。我将如何阻止它为零(为什么它首先是零?)? 显示自定义UITableViewCell 的代码,尤其是在声明ProfileImage 的位置以及如何将其初始化为initWithStyle 方法的一部分。 dequeueReusableCellForIdentifier: 将始终返回一个有效的单元格。你不需要检查它是否是nil @bobnoble 为迟到的回复道歉 - 我已经编辑了原始问题以包含 initwithStyle 方法(它太大,无法在此处发布) - 谢谢! 【参考方案1】:

当您尝试修改它时,您的图像出口很可能是nil

请注意,类属性的名称以小写字母开头是惯例 - 否则很容易将它们误认为是类名。所以cell.profileImage(基于@property (nonatomic, weak) IBOutlet UIImageView *profileImage;) 比较合适。

此外,您可以废弃 if (cell==nil) 块和 setNeedsDisplay

【讨论】:

谢谢,我会更改代码以匹配这个 - 从来不知道!是的,图像出口为零是一个问题,但我不知道为什么它是零,因为我(尝试)声明和实例化它:) 确保图像视图已连接到 Xib/Storyboard 文件中。【参考方案2】:

发现我的问题,原来我需要将所有代码移动到子类的 initwithstyle 函数中,最重要的是 synthesise 子类标题中的 UIImageView(不幸的是,我犯了菜鸟错误忘记这意味着 ImageView 只是保持为空)。

希望这对有同样问题的其他人有所帮助!

感谢所有帮助过的人!

【讨论】:

【参考方案3】:

这里发生了几件事......

    正如其他人所说,dequeueReusableCellWithIdentifier 总是 返回一个有效的UITableViewCell 所以nil 检查总是返回 NO 表示自定义单元格的 initWithStyle 永远不会被调用,并且 因此ProfileImage 永远不会被实例化,这就是它相等的原因 到nil。 目前有3个地方有代码可以修改 ProfileImage 层 (cellForRowAtIndexPath, willDisplayCell, 和自定义单元格的initWithStyle)。最后一个好像 合适的地方。 我怀疑在情节提要中,未设置自定义单元格的类 (即,说UITableViewCell)但应该是您的自定义名称 细胞。

推荐:

cellForRowAtIndexPath 并删除 willDisplayCell 方法。 删除nil签入cellForRowAtIndexPath 将故事板单元格的类设置为自定义单元格的名称

【讨论】:

再次感谢,我已经实施了您建议的所有更改。代码有点杂乱且重复,因为我在多个函数中复制了代码以尝试查看问题所在。原来我应该先查看子类(忘记合成 UIImageView)!非常感谢您的帮助!

以上是关于自定义 UITableViewCell 未更新的主要内容,如果未能解决你的问题,请参考以下文章

如何从 nib 中修复此“在托管对象上调用选择器 ... 已被 GC'ed”,其中包含未使用的自定义 UITableViewCell?

ios开发UI篇—使用纯代码自定义UItableviewcell实现一个简单的微博界面布局

自定义 UITableViewCell 中的 UIImageview 未正确显示

自定义 UITableViewCell 未出现在表格中

自定义 UITableViewCell 未正确加载

自定义 tableviewcell 动态高度未根据约束更新(以编程方式自动布局)