Swift中如何结合Coordinator使用类的自定义初始化器
你当前项目的Coordinator封装本身没有改动必要,核心原因是现有Coordinator的方法只接收已经初始化完成的视图控制器实例做展示动作,完全不涉及目标VC的初始化逻辑,只需要在调用Coordinator之前,把目标VC按你的自定义初始化规则构造完成、传入参数即可,具体分两类常见场景处理:
1. 从Storyboard加载的VC需要传入自定义参数
现有通过instantiateFromStoryboardName加载的VC,本身只完成了Storyboard关联的视图初始化,你只需要在拿到实例之后、调用Coordinator之前,把自定义初始化需要的参数赋值给VC的对应属性,再把完整实例传给Coordinator即可,完全不改动原有展示流程。
实际代码示例:
// 按原有逻辑从Storyboard加载VC实例 let orderDetailVC = OrderDetailViewController.instantiateFromStoryboardName(storyboardName: .GlobalStoryboard) // 给VC传入自定义初始化需要的业务参数 orderDetailVC.orderID = "ORD2024001" orderDetailVC.isFromPushEntry = true // 和原有逻辑完全一致,调用Coordinator完成展示 Coordinator.presentViewController(sourceViewController: self, destinationViewController: orderDetailVC)
如果你的参数需要在VC视图完全加载前就准备好,直接把上述赋值逻辑放到VC的awakeFromNib方法中完成初始化,避免出现视图渲染时参数未赋值的状态问题。
2. 纯代码实现、自带自定义初始化器的VC
这类VC本身不需要依赖Storyboard加载,直接调用自带的自定义初始化方法生成带全参数的实例,和Storyboard加载的实例一样,直接传给Coordinator即可。
实际代码示例:
// 直接调用自定义初始化方法生成带参数的VC实例 let phoneInputVC = PhoneInputViewController(inputScenario: .register, maxInputLength: 11) // 直接传入Coordinator完成展示 Coordinator.presentViewController(sourceViewController: self, destinationViewController: phoneInputVC)
不要为了适配传参逻辑去修改
Coordinator.presentViewController的方法签名,增加一堆带业务参数的重载方法。这种做法会让只负责转场职责的Coordinator和具体业务强耦合,破坏Coordinator模式的设计边界。Coordinator的核心职责仅为持有源控制器、完成转场动画与展示逻辑,VC的初始化逻辑、所需业务参数,完全由发起跳转的业务页面负责构造即可。
如果你的VC要求参数必须在实例化阶段就传入、不能后续赋值,可以为VC封装独立的便捷构造方法,替代Storyboard加载流程:
extension DatePickerViewController { static func make( minDate: Date, maxDate: Date, defaultSelectedDate: Date ) -> DatePickerViewController { let vc = DatePickerViewController(nibName: nil, bundle: nil) vc.minLimitDate = minDate vc.maxLimitDate = maxDate vc.selectedDate = defaultSelectedDate return vc } }
调用时直接使用make方法生成带全参数的实例,再传入Coordinator即可,和原有编码习惯完全兼容。
内容的提问来源于stack exchange,提问作者Ahmadreza

