子UIPageViewController转全屏模态展示时视图尺寸为0不显示问题
问题原因
- 子控制器移除流程不符合UIKit规范,生命周期方法调用顺序错误,导致外观转场回调失衡,出现
Unbalanced calls to begin/end appearance transitions警告 - 提前手动调用
didMoveToParentViewController:nil打乱了UIPageViewController的内部布局触发逻辑,其内部contentView无法获取正确的尺寸,最终frame变为0
修复方案
1. 先在类扩展中声明保存原始布局上下文的属性
@interface MyPageViewController () @property (nonatomic, weak) UIViewController *originalParentViewController; @property (nonatomic, weak) UIView *originalSuperview; @property (nonatomic, assign) CGRect originalFrame; // 使用AutoLayout布局可额外声明保存原约束 // @property (nonatomic, copy) NSArray *originalConstraints; @end
2. 修正点击手势的处理逻辑
严格遵循UIKit子控制器的移除规范,同时给视图添加初始尺寸避免布局失效:
- (void)handleTapGesture { // 保存原始状态,用于dismiss后恢复 self.originalParentViewController = self.parentViewController; self.originalSuperview = self.view.superview; self.originalFrame = self.view.frame; // 标准子控制器移除流程:先调用willMove,再移除视图,最后移除父控制器关联 [self willMoveToParentViewController:nil]; [self.view removeFromSuperview]; [self removeFromParentViewController]; // removeFromParentViewController会自动触发didMoveToParentViewController:nil,无需手动调用 // 给视图设置初始全屏frame,适配模态转场的布局上下文 self.view.frame = [UIScreen mainScreen].bounds; self.view.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight; self.modalPresentationStyle = UIModalPresentationFullScreen; [self.originalParentViewController presentViewController:self animated:YES completion:nil]; }
3. 补充dismiss后恢复原位置的逻辑
- (void)handleFullScreenDismiss { [self dismissViewControllerAnimated:YES completion:^{ // 按标准流程将控制器插回原父层级 [self.originalParentViewController addChildViewController:self]; self.view.frame = self.originalFrame; [self.originalSuperview addSubview:self.view]; [self didMoveToParentViewController:self.originalParentViewController]; // 清空临时保存的状态 self.originalParentViewController = nil; self.originalSuperview = nil; }]; }
内容的提问来源于stack exchange,提问作者ashipma
相关产品推荐
相关产品推荐

