You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何解决UICollectionViewCell便利初始化器的'self使用过早'错误?

问题解决:UICollectionViewCell便利初始化器报错处理

错误原因

你代码里的问题有两个:

  1. 便利初始化器必须先调用本类的指定初始化器,才能访问self的属性,但你在调用self.init()前就用了self.withDeleteButton,Swift不允许这种操作。
  2. 便利初始化器的参数传递逻辑错误,应该传入外部的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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.09 11:45:27