PageViewController混用同类型多页ViewController与不同类型ViewController是否可行
完全可以实现,UIPageViewController本身对数据源返回的控制器类型没有强制约束,完全支持混合使用两类ViewController,其中一类可复用对应多个页面,只需要对数据源逻辑做统一封装即可。
实现步骤
- 首先定义页面类型枚举,统一封装两类页面对应的参数:
一类是可复用的多页ViewController,需要传入对应页面的内容参数来展示不同内容;另一类是独立业务的单页ViewController,不需要复用参数。示例枚举定义如下:enum PageType { // 可复用类VC,携带对应页面的内容数据 case reusablePage(content: PageContentModel) // 独立单页VC,区分不同单页类型 case uniquePage(type: UniquePageEnum) } - 维护全局页面顺序配置数组,按你需要的页面顺序排列所有页面项:
// 数组顺序即为页面的实际排列顺序 let allPageList: [PageType] = [ .reusablePage(content: content1), .reusablePage(content: content2), .uniquePage(type: .userCenter), .reusablePage(content: content3), .uniquePage(type: .settings) ] - 在UIPageViewController的数据源方法中,根据索引对应的页面类型生成对应控制器即可:
// 工具方法:根据索引获取对应控制器 func controllerAt(index: Int) -> UIViewController? { guard index >= 0, index < allPageList.count else { return nil } let pageItem = allPageList[index] switch pageItem { case .reusablePage(let content): let vc = ReusableContentViewController() // 传入当前页面对应的数据 vc.currentContent = content return vc case .uniquePage(let type): switch type { case .userCenter: return UserCenterViewController() case .settings: return SettingsViewController() } } } // 数据源方法示例:返回上一个控制器 func pageViewController(_ pageViewController: UIPageViewController, viewControllerBefore viewController: UIViewController) -> UIViewController? { let currentIndex = // 先获取当前控制器对应的索引 return controllerAt(index: currentIndex - 1) } // 数据源方法示例:返回下一个控制器 func pageViewController(_ pageViewController: UIPageViewController, viewControllerAfter viewController: UIViewController) -> UIViewController? { let currentIndex = // 先获取当前控制器对应的索引 return controllerAt(index: currentIndex + 1) }
注意事项
- 可复用的ViewController要做好参数变更后的UI刷新逻辑,收到新的内容参数时要及时更新UI,避免展示上一个页面的旧内容
- 如果页面数量较多,可以额外加一层控制器缓存池,复用已经创建过的控制器,减少频繁创建销毁的性能开销
- 所有页面的索引判断要统一以
allPageList的数组索引为基准,不要通过控制器类型来反推索引,避免逻辑混乱
内容的提问来源于stack exchange,提问作者Dmitry Bakulin
相关产品推荐
相关产品推荐

