UIImageView 重复显示在另一个单元格中

Posted

技术标签:

【中文标题】UIImageView 重复显示在另一个单元格中【英文标题】:UIImageView repeats showing in another cells 【发布时间】:2016-10-07 06:41:07 【问题描述】:

我在表格单元格中的UIView 中动态添加UIImageView(作为缩略图)及其NSLayoutConstraints。我对此有两个问题。

    添加图像视图后,如果用户在此表中插入文本,仍然会显示图像。我的意思是,代替文本表打印一个图像。但是,如果我停止并重新运行该应用程序,这次文本将按原样显示。不过,如果我写一个文字图片来了。为什么以及我应该怎么做?

    我像这样设置图像及其约束:

    -(void)setThumbnail:(UIImageView)imageView 
    
    [self.messageView addSubview:imageView];
    
    NSLayoutConstraint *leadingOfThumbnail = [NSLayoutConstraint constraintWithItem:imageView attribute:NSLayoutAttributeLeading relatedBy:NSLayoutRelationEqual toItem:self.messageView attribute:NSLayoutAttributeLeading multiplier:1.0 constant:8.f];
    NSLayoutConstraint *trailingOfThumbnail = [NSLayoutConstraint constraintWithItem:imageView attribute:NSLayoutAttributeTrailing relatedBy:NSLayoutRelationEqual toItem:self.messageView attribute:NSLayoutAttributeTrailing multiplier:1.0 constant:-8.f];
    NSLayoutConstraint *topOfThumbnail = [NSLayoutConstraint constraintWithItem:imageView attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:self.messageView attribute:NSLayoutAttributeTop multiplier:1.0 constant:8.f];
    NSLayoutConstraint *bottomOfThumbnail = [NSLayoutConstraint constraintWithItem:imageView attribute:NSLayoutAttributeBottom relatedBy:NSLayoutRelationEqual toItem:self.messageView attribute:NSLayoutAttributeBottom multiplier:1.0 constant:-8.f];
    [self.messageView addConstraint:leadingOfThumbnail];
    [self.messageView addConstraint:trailingOfThumbnail];
    [self.messageView addConstraint:topOfThumbnail];
    [self.messageView addConstraint:bottomOfThumbnail];
    [self.messageView setTranslatesAutoresizingMaskIntoConstraints:NO];
    
    [self.messageView removeConstraints:[self.messageTextLabel constraints]];
    
    

在加载时,我得到一个约束错误。它说:

2016-10-07 09:35:32.532 application[3733:2922397] Unable to simultaneously satisfy constraints.     Probably at least one of the constraints in the following list is one you don't want.   Try this:       (1) look at each constraint and try to figure out which you don't expect;       (2) find the code that added the unwanted constraint or constraints and fix it.     (Note: If you're seeing NSAutoresizingMaskLayoutConstraints that you don't understand, refer to the documentation for the UIView property translatesAutoresizingMaskIntoConstraints)  (
    "NSAutoresizingMaskLayoutConstraint:0x1281474d0 h=--& v=--& UIImageView:0x126d7e020.midY == + 100",
    "NSAutoresizingMaskLayoutConstraint:0x128147520 h=--& v=--& V:[UIImageView:0x126d7e020(200)]",
    "NSLayoutConstraint:0x126d6c880 V:|-(8)-[UIImageView:0x126d7e020]   (Names: '|':UIView:0x1281480d0 )" )

Will attempt to recover by breaking constraint  NSLayoutConstraint:0x126d6c880 V:|-(8)-[UIImageView:0x126d7e020]   (Names: '|':UIView:0x1281480d0 )

Make a symbolic breakpoint at UIViewAlertForUnsatisfiableConstraints to catch this in the debugger. The methods in the UIConstraintBasedLayoutDebugging category on UIView listed in <UIKit/UIView.h> may also be helpful.

我检查过,我设置的前导和顶部约束会导致此错误。他们已经不能正常工作了。我的图像是 200 * 200,因此它不需要高度和宽度限制。我只想要消息视图中的 8 pt 前导、尾随、顶部、底部。有什么问题?

谢谢。

第一个问题的解释编辑:表格随机放置 UIImageView,多个单元格 - 不是应该的。

【问题讨论】:

[self.messageView addSubview:imageView]; 这是罪魁祸首,因为单元格被重复使用。由于您似乎为您的单元格使用了自定义 .m,因此在prepareForReuse 中,从self.messageView 中删除所有属于 UIImageView 的子视图。 @narsimelous :单元格重用缓存动态添加到单元格的图像视图的问题。编写一些 resetThumbnail 方法来检查图像视图是否存在,然后将其删除并将单元格约束重置回初始状态。在每次 prepareForReuse 调用时重置它。 【参考方案1】:

您可能想要实现 prepareForReuse 方法并在那里进行一些清理,将 imageView 设置为 nil 并将其从此处的子视图中删除。 当您的单元格出列并即将在 tableview 中重用时,将调用此方法。

【讨论】:

是的,这就是答案。非常感谢!【参考方案2】:

对于第一个问题,您可以在从 tableview 出队后简单地将单元格图像设置为 nil。

对于第二个问题,在 ImageView 初始化后添加这一行,以避免将 autoresizingmask 转换为约束:

imageView.translatesAutoresizingMaskIntoConstraints = false

【讨论】:

我试过了,但初始化后没有。谢谢你的第二个问题!第一部分呢? 你的第一个问题我不是很明白,你能解释得更好或者加个gif吗?【参考方案3】:

我相信您的问题是由于 dequeCell 功能。 UITbableView 回收单元格。因此,如果您将图像放在一个单元格中,它就有可能出现在另一个单元格中。

要解决这个问题,您需要在 cellForRowAtIndexPath 中放置一些条件。

这些条件将检查您是否要在当前单元格或图像中显示文本,或两者兼而有之。

如果它只需要文本,则需要从该单元格中删除图像。

如果您仍然遇到问题,请分享您的 cellForRowAtIndexPath 代码。

【讨论】:

但我以编程方式添加图像。我该怎么做? 一种方法是将 UIImageView 放在您的自定义 UITableViewCell 类中。仅在需要图像时才对其进行初始化。如果不是,则将其设置为 nil 并将其从 superView 中删除。另一种方法是遍历所有 Cell 子视图并检查 UIImaqeViewClass。删除该子视图。虽然我更喜欢第一种方式 有道理。谢谢!我不希望它作为 IBOutlet。我认为这不会引起问题吗? @Shayan Jalil 如果您不希望它作为 IBOutlet,只需在您的单元格类中声明一个 UIIMageView 属性。然后在需要时初始化它,就像您现在在 setThumbnail 方法中所做的那样。但是这次你将把这个方法放在你的单元类中。当您不需要图像时,您只需从超级视图中删除图像

以上是关于UIImageView 重复显示在另一个单元格中的主要内容,如果未能解决你的问题,请参考以下文章

在 tableView 单元格中显示和隐藏 UIImageView

在具有透明度的 UITableView 单元格中更新 UIImageView

使用 didSelect 方法在 viewDidLoad 之后在单元格中显示图像

UIimageview 在 uitableviewcell 中显示不止一次

UICollectionView 重复单元格

UICollectionView - 在其他单元格中重复的子视图实例