UIPageViewController切换崩溃:[views count]==3,窗口展示异常求助
解决UIPageViewController在窗口直接展示时切换页面崩溃的问题
我之前踩过一模一样的坑!当UIPageViewController的父视图不是通过导航栈push,而是直接在窗口中展示时,用.scroll转场风格调用setViewControllers(...animated:true...)就会抛出Invalid parameter not satisfying: [views count] == 3的崩溃,简直头疼。
问题根源
本质是UIPageViewController在窗口直接展示时,视图的布局流程还没走完,内部的视图层级还没达到带动画切换所需的3个视图的要求,这时候强行触发带动画的页面切换就会触发断言失败。
可行解决方案
方案1:延迟到视图完全布局完成后再调用带动画的切换
把带动画的setViewControllers调用放到viewDidAppear方法里,或者用一个极短的延迟确保布局完成:
override func viewDidAppear(_ animated: Bool) { super.viewDidAppear(animated) // 在这里执行页面切换,此时视图布局已经完全完成 let nextVC = YourNextViewController() self.setViewControllers([nextVC], direction: .forward, animated: true, completion: nil) }
如果因为业务逻辑不能等到viewDidAppear,也可以用异步延迟:
// 比如在viewDidLoad里调用 override func viewDidLoad() { super.viewDidLoad() DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) { [weak self] in guard let self = self else { return } let nextVC = YourNextViewController() self.setViewControllers([nextVC], direction: .forward, animated: true, completion: nil) } }
方案2:先无动画初始化,再带动画切换
如果必须在较早时机触发切换,可以先做一次无动画的页面设置,让UIPageViewController的内部视图层级先构建完成,之后再执行带动画的切换:
override func viewDidLoad() { super.viewDidLoad() // 先无动画设置初始页面,确保内部视图结构正确 let initialVC = YourInitialViewController() self.setViewControllers([initialVC], direction: .forward, animated: false, completion: nil) // 后续需要切换时,再使用animated: true DispatchQueue.main.async { [weak self] in guard let self = self else { return } let nextVC = YourNextViewController() self.setViewControllers([nextVC], direction: .forward, animated: true, completion: nil) } }
关于不适用的方案
StackOverflow上提到的另一种方案可能是修改转场风格为.pageCurl,但显然你需要保持.scroll的转场效果,所以这个方案直接排除就好。
内容的提问来源于stack exchange,提问作者Zubair
相关产品推荐
相关产品推荐

