Swift:如何通过代码创建可复用视图?以自定义HeaderView为例
改造可复用的程序化HeaderView方案
要让你的HeaderView支持复用,核心思路就是把可变的标签文本作为初始化参数传入,把其他固定属性(比如背景、字体、布局等)封装在视图内部,这样每次创建实例时只需要传入不同的文本即可。下面是具体的改造步骤和代码示例:
1. 重构HeaderView类,添加带标题参数的初始化方法
首先在你的HeaderView中,把标题文本作为初始化的必填参数,同时兼容代码初始化和IB(xib/storyboard)初始化两种场景:
import UIKit class HeaderView: UIView { // 声明标题标签,提前设置固定样式 private let titleLabel: UILabel = { let label = UILabel() label.font = UIFont.systemFont(ofSize: 18, weight: .semibold) label.textColor = .darkText label.translatesAutoresizingMaskIntoConstraints = false return label }() // MARK: - 初始化方法 /// 代码初始化时调用,直接传入标题文本 init(title: String, frame: CGRect = .zero) { super.init(frame: frame) setupFixedStyle(with: title) } /// IB初始化时调用(如果需要从xib/storyboard拖拽使用) required init?(coder: NSCoder) { super.init(coder: coder) // IB创建时默认设空标题,后续可通过setTitle方法修改 setupFixedStyle(with: "") } // MARK: - 内部配置固定样式 private func setupFixedStyle(with title: String) { // 设置视图固定属性,比如背景色 backgroundColor = .systemGray6 // 添加标题标签并设置自适应约束 addSubview(titleLabel) NSLayoutConstraint.activate([ titleLabel.leadingAnchor.constraint(equalTo: leadingAnchor, constant: 16), titleLabel.centerYAnchor.constraint(equalTo: centerYAnchor), titleLabel.trailingAnchor.constraint(lessThanOrEqualTo: trailingAnchor, constant: -16) ]) // 赋值传入的标题文本 titleLabel.text = title } // 可选:提供动态修改标题的方法,方便后续更新 func setTitle(_ title: String) { titleLabel.text = title } }
2. 创建多个不同文本的HeaderView实例
现在你可以轻松创建多个仅标题不同的HeaderView,直接在代码中初始化并添加到父视图即可:
// 示例:在ViewController中使用 class ViewController: UIViewController { override func viewDidLoad() { super.viewDidLoad() view.backgroundColor = .white // 创建三个不同标题的HeaderView实例 let collectionHeader = HeaderView(title: "我的收藏") let historyHeader = HeaderView(title: "最近浏览") let recommendHeader = HeaderView(title: "推荐内容") // 用StackView快速排列三个Header(也可以单独设置约束) let stackView = UIStackView(arrangedSubviews: [collectionHeader, historyHeader, recommendHeader]) stackView.axis = .vertical stackView.spacing = 12 stackView.translatesAutoresizingMaskIntoConstraints = false view.addSubview(stackView) // 设置StackView的约束 NSLayoutConstraint.activate([ stackView.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor, constant: 20), stackView.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 16), stackView.trailingAnchor.constraint(equalTo: view.trailingAnchor, constant: -16) ]) // 如果需要动态修改标题,直接调用方法即可 // collectionHeader.setTitle("更新后的收藏夹") } }
为什么这样改造?
- 复用性拉满:所有固定样式都封装在
HeaderView内部,不用每次创建都重复写布局、字体、背景色等冗余代码 - 维护成本低:后续要修改Header的样式(比如改字体大小、背景色),只需要修改
setupFixedStyle方法,所有实例都会自动同步更新 - 使用更简洁:创建实例时只需要关注可变的标题参数,代码逻辑清晰易懂
内容的提问来源于stack exchange,提问作者user298519
相关产品推荐
相关产品推荐

