Swift实现UIPageViewController子控制器间无segue传值方法
跨UIPageViewController子控制器代理传值失效的修复方案
核心故障根因
你当前的代理链路从初始化环节就存在完全的断层:
- 你在
MobileNumberViewController中定义了delegate属性、也在文本框编辑结束时写了代理调用方法,但从来没有把负责接收数据的DiseasesViewController实例赋值给这个delegate属性 - 两个子控制器本身没有直接的持有关系:所有子控制器都是由自定义的
PageViewController容器统一初始化、统一管理的,两个子控制器互相拿不到对方的实例,自然delegate永远是nil,代理方法不可能触发 - 常见的次生问题:如果delegate属性用了
strong修饰,就算后面补了赋值步骤,也会产生循环引用,导致代理对象被提前释放,链路同样会断
快速验证故障的方法:在你写的
textFieldDidEndEditing回调里打印self.delegate的内存地址,90%的概率输出为nil,这就是代理不触发的直接原因。
适配你现有代码结构的落地修复步骤
全程不需要修改你现有的PageController懒加载子控制器、配置PageControl的逻辑,只需要补全缺失的绑定环节即可:
1. 调整代理协议的基础配置
把代理协议抽成两个子控制器都能访问的公共定义,避免两个子控制器直接互相import增加耦合:
@protocol NameAndMobileDelegates <NSObject> - (void)didCollectedUserName:(NSString *)userName mobile:(NSString *)mobile; @end // 在MobileNumberViewController.h中声明delegate属性,必须用weak修饰,避免循环引用 @property (nonatomic, weak) id<NameAndMobileDelegates> delegate;
2. 在自定义PageViewController容器类中完成delegate绑定
你本来就在容器里懒加载所有4个子控制器,直接在拿到两个子控制器实例的位置完成绑定即可,不让两个子控制器产生直接关联:
- (void)setupChildViewControllerList { // 你原有的懒加载逻辑 UIViewController *firstVC = [UIViewController new]; MobileNumberViewController *collectVC = [[MobileNumberViewController alloc] init]; UIViewController *thirdVC = [UIViewController new]; DiseasesViewController *submitVC = [[DiseasesViewController alloc] init]; // 核心缺失的绑定步骤:把第四个提交页设置为第二个采集页的代理 collectVC.delegate = submitVC; self.childViewControllers = @[firstVC, collectVC, thirdVC, submitVC]; // 你原有的UIPageControl配置逻辑完全保留即可 }
3. 在DiseasesViewController中实现代理方法接收数据
让提交页遵循代理协议,把传过来的用户数据存在自身的成员变量里,等触发按钮点击写库时直接取用:
// 在DiseasesViewController.m中 @interface DiseasesViewController () <NameAndMobileDelegates> @property (nonatomic, copy) NSString *savedUserName; @property (nonatomic, copy) NSString *savedMobile; @end @implementation DiseasesViewController - (void)didCollectedUserName:(NSString *)userName mobile:(NSString *)mobile { // 收到采集页传来的数据,本地暂存 self.savedUserName = userName; self.savedMobile = mobile; } // 你原有的提交按钮写数据库逻辑 - (void)onSubmitButtonTapped { // 直接用暂存的savedUserName、savedMobile组装入库数据即可 } @end
额外优化提示
- 不要让UIPageControl承担数据中转的职责,它本来就是纯UI指示器,只负责反馈当前展示的页码即可,不用参与数据传递流程
- 如果后续需要增加更多跨页面的数据传递,都可以复用这个模式:在容器层统一完成所有子控制器的依赖绑定,子控制器之间完全不需要直接接触,耦合度最低
- 不要为了图省事用全局单例、本地通知做跨页面传值,那类方案的数据链路可追踪性差,后续维护成本比现在的代理绑定方案高很多
内容的提问来源于stack exchange,提问作者mohamad
相关产品推荐
相关产品推荐

