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

Swift 4:如何为两个ViewController共用一个Xib文件?

两个ViewController共用一个Xib文件?当然可以!Swift 4实现指南

完全没问题让多个ViewController复用同一个Xib界面,在Swift 4里有两种常用的实现方式,我给你详细拆解:

方法一:直接将Xib作为ViewController的根视图(快速实现)

这种方式适合简单的复用场景,不用额外创建自定义View类:

  1. 创建共用Xib:新建一个Xib文件(比如命名为SharedContentView.xib),设计好你要复用的界面。注意:不要在Xib的File's Owner中指定任何ViewController类,因为我们要给多个VC共用。
  2. 在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架构,代码结构清晰,复用性更强,适合复杂的复用场景:

  1. 创建自定义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
    }
}
  1. 创建对应Xib:新建SharedCustomView.xib,把Xib的File's Owner设置为SharedCustomView,然后把Xib里的根View和控件拖线到SharedCustomView类中。
  2. 在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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.29 07:16:59