从Storyboard继承BaseViewController后IB设置不生效,该如何解决?
问题根源
你在Storyboard里设计的BaseViewController是一个具体的视图控制器实例,而RootViewController继承的是BaseViewController这个代码类——这两者完全不是一回事。IB里给那个BaseVC实例设置的背景色,只会作用于它自己,不会自动传递给子类的实例,除非你做了正确的UI继承配置。
解决办法
方法1:用Storyboard官方的「视图控制器继承」(最推荐)
这是Apple官方支持的Storyboard UI继承方式,步骤如下:
- 先确认你的BaseVC场景配置正确:
- 在Storyboard里选中
BaseViewController的场景,打开右侧「Identity Inspector」(⌥⌘3),确保「Class」字段已经设置为BaseViewController代码类。
- 在Storyboard里选中
- 创建RootVC的Storyboard场景并继承BaseVC:
- 拖一个新的
ViewController到Storyboard中,选中它,在「Identity Inspector」的「Class」下拉选择RootViewController。 - 往下找,找到「Inherit From」选项,点击下拉菜单选择你之前设计的
BaseViewController场景(注意是场景名称,不是代码类名)。 - 完成后,这个RootVC场景会自动继承BaseVC里的所有UI设置,包括你在IB里设置的绿色背景色,运行时就能正常显示了。
- 拖一个新的
方法2:把BaseVC的UI抽成XIB文件
如果不想在Storyboard里搞场景继承,也可以把BaseVC的UI单独做成XIB,让子类共享这个布局:
- 创建
BaseViewController.xib文件:- 新建XIB文件,设置「File's Owner」为
BaseViewController,然后在XIB里设计背景色等UI元素(和你之前在Storyboard里的操作一样)。
- 新建XIB文件,设置「File's Owner」为
- 修改
BaseViewController的代码,让它默认加载这个XIB:class BaseViewController: UIViewController { override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: Bundle?) { super.init(nibName: nibNameOrNil ?? "BaseViewController", bundle: nibBundleOrNil) } required init?(coder: NSCoder) { super.init(coder: coder) } } - 之后不管你是用代码创建
RootViewController(),还是在Storyboard里给RootVC场景设置类为RootViewController,它都会自动加载BaseVC的XIB布局,背景色自然生效。
方法3:在BaseVC代码里同步IB设置(临时方案)
如果不想改现有Storyboard结构,也可以在BaseVC的代码里手动同步IB的设置,虽然有点冗余但能快速解决问题:
class BaseViewController: UIViewController { override func viewDidLoad() { super.viewDidLoad() // 把IB里设置的背景色用代码再写一遍,子类继承后会执行这段逻辑 view.backgroundColor = .green } }
补充说明
为什么你用代码设置BaseVC的背景色就生效?因为代码是写在BaseViewController类里的,子类继承后会自动执行父类的viewDidLoad方法,所以能拿到这个设置;但IB里的设置是属于某个特定实例的,和代码类的继承没有直接关联,所以不会自动传递。
内容的提问来源于stack exchange,提问作者iOS
相关产品推荐
相关产品推荐

