Swift 4:如何为两个ViewController共用一个Xib文件?
两个ViewController共用一个Xib文件?当然可以!Swift 4实现指南
完全没问题让多个ViewController复用同一个Xib界面,在Swift 4里有两种常用的实现方式,我给你详细拆解:
方法一:直接将Xib作为ViewController的根视图(快速实现)
这种方式适合简单的复用场景,不用额外创建自定义View类:
- 创建共用Xib:新建一个Xib文件(比如命名为
SharedContentView.xib),设计好你要复用的界面。注意:不要在Xib的File's Owner中指定任何ViewController类,因为我们要给多个VC共用。 - 在ViewController中加载Xib:在每个需要复用这个Xib的VC里,重写
loadView方法(系统加载视图的标准入口),把Xib加载为当前VC的根视图:
class FirstVC: UIViewController { override func loadView() { // 从Bundle中加载Xib guard let sharedView = Bundle.main.loadNibNamed("SharedContentView", owner: self, options: nil)?.first as? UIView else { fatalError("Failed to load SharedContentView.xib") } self.view = sharedView // 给Xib里的控件设置内容/事件(这里用tag识别控件,比如给label设tag=100) if let titleLabel = sharedView.viewWithTag(100) as? UILabel { titleLabel.text = "我是第一个VC的标题" } } }
第二个VC的代码逻辑几乎一致,只需修改控件的内容或事件:
class SecondVC: UIViewController { override func loadView() { guard let sharedView = Bundle.main.loadNibNamed("SharedContentView", owner: self, options: nil)?.first as? UIView else { fatalError("Failed to load SharedContentView.xib") } self.view = sharedView if let titleLabel = sharedView.viewWithTag(100) as? UILabel { titleLabel.text = "我是第二个VC的标题" } } }
⚠️ 注意:用tag识别控件虽然快捷,但代码可读性差,不适合复杂界面。
方法二:封装自定义View(推荐,更优雅)
这种方式符合MVC架构,代码结构清晰,复用性更强,适合复杂的复用场景:
- 创建自定义View类:新建
SharedCustomView.swift文件,继承自UIView,用来管理Xib的控件和通用逻辑:
class SharedCustomView: UIView { // 关联Xib里的控件(直接在Xib里拖线到这个类即可) @IBOutlet weak var titleLabel: UILabel! @IBOutlet weak var actionBtn: UIButton! // 重写初始化方法,统一加载Xib override init(frame: CGRect) { super.init(frame: frame) setupXib() } required init?(coder: NSCoder) { super.init(coder: coder) setupXib() } private func setupXib() { // 加载Xib文件 let nib = UINib(nibName: "SharedCustomView", bundle: nil) guard let xibView = nib.instantiate(withOwner: self, options: nil).first as? UIView else { return } // 设置Xib视图的约束,让它铺满当前View xibView.frame = bounds xibView.autoresizingMask = [.flexibleWidth, .flexibleHeight] addSubview(xibView) } // 提供公共方法,让外部VC可以设置内容 func configure(with title: String) { titleLabel.text = title } }
- 创建对应Xib:新建
SharedCustomView.xib,把Xib的File's Owner设置为SharedCustomView,然后把Xib里的根View和控件拖线到SharedCustomView类中。 - 在ViewController中使用自定义View:在每个VC里初始化这个自定义View,添加到当前VC的视图上,并设置内容和事件:
class FirstVC: UIViewController { override func viewDidLoad() { super.viewDidLoad() let sharedView = SharedCustomView(frame: view.bounds) sharedView.configure(with: "第一个VC专属内容") sharedView.actionBtn.addTarget(self, action: #selector(firstBtnTapped), for: .touchUpInside) view.addSubview(sharedView) } @objc private func firstBtnTapped() { print("第一个VC的按钮被点击啦") } }
class SecondVC: UIViewController { override func viewDidLoad() { super.viewDidLoad() let sharedView = SharedCustomView(frame: view.bounds) sharedView.configure(with: "第二个VC专属内容") sharedView.actionBtn.addTarget(self, action: #selector(secondBtnTapped), for: .touchUpInside) view.addSubview(sharedView) } @objc private func secondBtnTapped() { print("第二个VC的按钮被点击啦") } }
两种方式对比
- 方法一:快速上手,适合简单界面,但控件管理不够优雅,维护成本高。
- 方法二:代码结构清晰,复用性强,适合复杂界面,是生产环境中的推荐方案。
内容的提问来源于stack exchange,提问作者Rob
相关产品推荐
相关产品推荐

