Coordinator模式下UITabBarController多Storyboard VC实例化问题
解决方案
核心修改思路
原来的协议扩展硬编码了Main作为固定的Storyboard名称,我们只需要在协议中新增可自定义的Storyboard名称属性,提供默认值兼容原有逻辑即可,完全不需要修改现有调用代码。
完整修改代码
首先更新Storyboarded协议定义和默认扩展:
protocol Storyboarded { // 新增自定义Storyboard名称属性 static var storyboardName: String { get } // 可选新增自定义Identifier属性,默认用类名,兼容特殊场景 static var storyboardIdentifier: String { get } static func instantiate() -> Self } extension Storyboarded where Self: UIViewController { // 默认用Main.storyboard,原有使用Main的控制器无需修改 static var storyboardName: String { "Main" } // 默认用类名作为Identifier,和原有逻辑保持一致 static var storyboardIdentifier: String { String(describing: self) } static func instantiate() -> Self { let storyboard = UIStoryboard(name: storyboardName, bundle: .main) return storyboard.instantiateViewController(identifier: storyboardIdentifier) as! Self } }
不同模块控制器使用示例
如果对应控制器在其他Storyboard中,只需要重写storyboardName属性即可,其他逻辑完全不变:
- 日历模块控制器放在
Calendar.storyboard中:
class CalendarViewController: UIViewController, Storyboarded { // 仅需加这一行指定对应的Storyboard名称 static var storyboardName: String { "Calendar" } }
- 统计模块控制器放在
Chart.storyboard中:
class ChartViewController: UIViewController, Storyboarded { static var storyboardName: String { "Chart" } }
额外适配场景
如果某控制器的Storyboard Identifier和类名不一致,额外重写storyboardIdentifier属性即可:
class SpecialViewController: UIViewController, Storyboarded { static var storyboardName: String { "Special" } static var storyboardIdentifier: String { "CustomId" } }
内容的提问来源于stack exchange,提问作者TeddyKen
相关产品推荐
相关产品推荐

