我有一个CustomCollectionViewController
和一个CustomCollectionViewCell
。我将一个UIImageView
拖放到情节提要中的CustomCollectionViewCell
上,并将其绑定到代码中。
然后,我尝试使用此行初始化collectionView(_:cellForItemAt:)
中的单元格:
customCell.imageView = UIImageView(image: images[indexPath.item])
它不起作用,customCell.imageView
返回时nil
是collectionView(_:cellForItemAt:)
。但是有了imageCell.imageView.image = images[indexPath.item]
,它就可以了。
为什么会这样?谢谢。
代码段:
在class CustomCollectionViewController
内
override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "imageCell", for: indexPath)
if let imageCell = cell as? ImageCollectionViewCell, images[indexPath.item] != nil {
imageCell.imageView = UIImageView(image: images[indexPath.item]) // doesn't work, cell.imageView would be nil
imageCell.imageView.image = images[indexPath.item] // work
}
return cell
}
并且:
class CustomCollectionViewCell: UICollectionViewCell {
@IBOutlet weak var imageView: UIImageView!
}
答案 0 :(得分:1)
长答案:
让您将旧ImageView(情节提要中的一个)命名为A,将新ImageView(在代码中创建)命名为B UIImageView(image: images[indexPath.item])
该变量将被称为引用
您已将参考设置为弱参考,这意味着,一旦失去任何强参考(例如处于视图层次结构中),它就会被销毁。当您将其分配为B时,该B未分配给其他任何地方,因此它立即被销毁,因此您的引用变为nil。只要您将其从层次结构中删除,您的A仍在单元格中(在子视图数组中,并且数组倾向于保留强引用)。您必须了解链接引用(弱或强)与作为视图的子视图(强)之间的区别。在对代码进行任何更改之前,imageView有两个链接-代码中的弱指针和单元层次结构中的强指针。当您用B替换参照时,A失去了弱点,但在单元格本身中仍然具有强参照。 B只是很弱,所以在实际使用之前就被立即摧毁了
您的逻辑也有问题。仅仅因为您更改对B imageView的引用,并不意味着该图像将出现在您的单元格中。您的B需要设置为框架或约束,并添加到某些视图层次结构(单元格)中。您实际需要的只是将A.image属性更改为新图像,就是imageCell.imageView.image = images[indexPath.item]
请阅读有关内存管理和弱而有力的参考文献的更多信息
简短答案:
删除此行
imageCell.imageView = UIImageView(image: images[indexPath.item])
所以您的代码看起来像
override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "imageCell", for: indexPath)
if let imageCell = cell as? ImageCollectionViewCell,
let image = images[indexPath.item]
{
imageCell.imageView.image = image
}
return cell
}
答案 1 :(得分:0)
由于imageView被声明为weak
@IBOutlet weak var imageView: UIImageView!
为其分配新实例使其nil
,因为lhs无法保留rhs,请注意警告
如果您希望它正常工作,请删除weak
,因为默认值为strong
@IBOutle var imageView: UIImageView!
但是对于您当前的情况没有任何意义,因此只需分配图片
答案 2 :(得分:0)
设置imageView属性是一个坏主意。这是一个通过情节提要/ xib实例化的出口。我猜测您创建的新UIImageView不会保留,因为imageView被声明为弱。
如果首先使用“界面”构建器添加视图或控件,则应避免“重新创建”此类视图或控件。
答案 3 :(得分:0)
就像已经提到的其他答案一样,问题是imageCell.imageView
较弱,因此它仅引用牢固保留在另一个位置的ImageView。
imageCell.imageView最初引用您拖放到情节提要中的ImageView。当一个视图包含在另一个视图中时,它将被强烈保留。
如果要替换该ImageView,则需要创建对新ImageView的强引用,例如,将其添加到另一个View中,如下所示:
let newImageView = UIImageView(image: images[indexPath.item])
imageCell.contentView.addSubview(newImageView)
imageCell.imageView = newImageView
但是正如其他人之前提到的,最好只替换当前ImageView的UIImage。