如何解决UICollectionViewCell便利初始化器的'self使用过早'错误?
问题解决:UICollectionViewCell便利初始化器报错处理
错误原因
你代码里的问题有两个:
- 便利初始化器必须先调用本类的指定初始化器,才能访问
self的属性,但你在调用self.init()前就用了self.withDeleteButton,Swift不允许这种操作。 - 便利初始化器的参数传递逻辑错误,应该传入外部的
showsDeleteButton,而非未初始化的withDeleteButton。
修正方案一:正确使用便利初始化器
先调用指定初始化器完成self初始化,再设置按钮状态并配置UI:
class MediaSelectionCell: UICollectionViewCell { var withDeleteButton = false { didSet { // 属性变化时自动更新按钮显示状态 deleteButton.isHidden = !withDeleteButton } } private let deleteButton = UIButton(type: .system) convenience init(showsDeleteButton: Bool) { // 先调用指定初始化器(这里用默认frame,可根据需求自定义) self.init(frame: .zero) // 初始化完成后再设置属性 self.withDeleteButton = showsDeleteButton setupDeleteButton() } override init(frame: CGRect) { super.init(frame: frame) setupDeleteButton() // 初始化时根据默认值设置按钮状态 deleteButton.isHidden = !withDeleteButton } required init?(coder: NSCoder) { fatalError("init(coder:) has not been implemented") } private func setupDeleteButton() { // 配置按钮样式与布局 deleteButton.setTitle("删除", for: .normal) deleteButton.translatesAutoresizingMaskIntoConstraints = false contentView.addSubview(deleteButton) NSLayoutConstraint.activate([ deleteButton.topAnchor.constraint(equalTo: contentView.topAnchor, constant: 8), deleteButton.trailingAnchor.constraint(equalTo: contentView.trailingAnchor, constant: -8), deleteButton.widthAnchor.constraint(equalToConstant: 60), deleteButton.heightAnchor.constraint(equalToConstant: 30) ]) } }
修正方案二:重载指定初始化器
如果希望更明确地传递初始化参数,可以直接重载指定初始化器:
class MediaSelectionCell: UICollectionViewCell { var withDeleteButton = false private let deleteButton = UIButton(type: .system) // 重载指定初始化器,直接接收按钮状态参数 init(frame: CGRect, showsDeleteButton: Bool) { self.withDeleteButton = showsDeleteButton super.init(frame: frame) setupDeleteButton() deleteButton.isHidden = !showsDeleteButton } override init(frame: CGRect) { super.init(frame: frame) setupDeleteButton() deleteButton.isHidden = true // 默认隐藏删除按钮 } required init?(coder: NSCoder) { fatalError("init(coder:) has not been implemented") } private func setupDeleteButton() { // 按钮配置代码同上 deleteButton.setTitle("删除", for: .normal) deleteButton.translatesAutoresizingMaskIntoConstraints = false contentView.addSubview(deleteButton) NSLayoutConstraint.activate([ deleteButton.topAnchor.constraint(equalTo: contentView.topAnchor, constant: 8), deleteButton.trailingAnchor.constraint(equalTo: contentView.trailingAnchor, constant: -8), deleteButton.widthAnchor.constraint(equalToConstant: 60), deleteButton.heightAnchor.constraint(equalToConstant: 30) ]) } }
使用方式
- 方案一调用:
let cell = MediaSelectionCell(showsDeleteButton: true) - 方案二调用:
let cell = MediaSelectionCell(frame: .zero, showsDeleteButton: true)
内容的提问来源于stack exchange,提问作者David Henry
相关产品推荐
相关产品推荐

