代码之家  ›  专栏  ›  技术社区  ›  HongJian

向自定义tableviewcells添加约束的最佳位置是哪里?

  •  0
  • HongJian  · 技术社区  · 6 年前

    我知道添加约束的最佳位置是viewDidLoad,但对于自定义视图,尤其是自定义单元格,我希望将所有这些布局细节隐藏到自身中,而不向其控制器公开。我不想让VC向它的视图发送消息,因为它对耦合有一点贡献,这是我最讨厌的。那么我应该在哪里添加约束,在init方法或layoutSubview中,或者其他什么地方?

    2 回复  |  直到 6 年前
        1
  •  2
  •   Rob    6 年前

    对于 UITableViewCell 子类中,通常会在将子视图添加到视图层次的任何位置添加约束。

    • 对于NIB中的控件,我将在Interface Builder中添加约束,从而消除了以编程方式执行任何操作的需要。

    • 如果您使用的是NIB,但出于某种原因选择不将约束放在XIB中,那么您可以通过编程方式在中创建约束 awakeFromNib 。您不会尝试在中添加这些约束 init(coder:) ,因为这些插座尚未连接。你会想在 awakeFromNib ,此时它们已连接。

    • 如果您使用的是NIB,但以编程方式添加了一些额外的子视图,那么您需要再次在中添加这些子视图及其关联的约束 awakeFromNib 。如果这些新子视图不需要任何 @IBOutlet 参考文献,理论上你也可以在 初始化(编码器:)

    • 如果您没有使用NIB,而是完全以编程方式创建单元的子视图,那么通常可以在 初始化(编码器:) init(style:reuseIdentifier:) 取决于如何 cellForRowAt 实例化单元格。

      • 现在,通常为表视图的重用标识符注册一个类,然后 cellForRowAt手机 只会 dequeueReusableCell(withIdentifier:for:) ,在这种情况下,您可以在 初始化(编码器:)

      • 在iOS之前 dequeueReusableCell(withIdentifier:for:) method 常规(即,我们只进行了表演,没有 IndexPath 参数),我们会调用 dequeueReusableCell(withIdentifier:) ,如果它返回 nil ,我们将使用 init(样式:reuseIdentifier:) 。但这项技术已不再被广泛使用。

      • 从历史的角度来看,值得注意的是,您可能仍然会偶然发现在中添加单元格子视图的旧代码 cellForRowAt手机 。但我们通常更倾向于将此单元格自定义代码移动到 UITableViewCell 子类帮助最小化视图控制器膨胀。

    最重要的是,无论在何处将子视图添加到视图层次结构,都可以添加约束,而将约束放在哪个方法中取决于如何实例化单元格。

        2
  •  0
  •   billgert    6 年前

    如果不使用故事板,我想说添加约束的最佳位置是 UITableViewCell :

    class CustomTableViewCell : UITableViewCell {
    
        lazy var subview: UIView = {
            let view = UIView()
            view.backgroundColor = .orange
            view.translatesAutoresizingMaskIntoConstraints = false
            return view
        }()
    
        override init(style: UITableViewCellStyle, reuseIdentifier: String?) {
            super.init(style: style, reuseIdentifier: reuseIdentifier)
    
            contentView.addSubview(subview)
            NSLayoutConstraint.activate([
                subview.leadingAnchor.constraint(equalTo: contentView.leadingAnchor),
                subview.trailingAnchor.constraint(equalTo: contentView.trailingAnchor),
                subview.topAnchor.constraint(equalTo: contentView.topAnchor),
                subview.bottomAnchor.constraint(equalTo: contentView.bottomAnchor),
                subview.heightAnchor.constraint(equalToConstant: 230.0)
            ])
        }
    
        required init?(coder aDecoder: NSCoder) {
            fatalError("init(coder:) has not been implemented")
        }
    
    }