UIPageViewController
创建 PageViewController
1// transitionStyle 指定页面切换时的过渡样式
2// navigationOrientation 指定页面切换导航方向 水平,垂直
3let pageVC = UIPageViewController(transitionStyle: .scroll, navigationOrientation: .vertical)
4
5// 设置 PageViewController 的 dataSource 和 delegate
6pageVC.delegate = ...
7
8pageVC.dataSource = ...
9
10// 设置 PageViewController 的 viewControllers
11pageVC.setViewControllers([...], direction: .forward, animated: true, completion: nil)
数据与页面联动
1/// 获取页面对应的数据下标索引
2/// - Parameter entryPage: 页面
3/// - Returns: 下标索引
4private func indexOf(ViewController viewController: UIViewController) -> Int? {
5 // dataSource 中查找 viewController 的索引
6 // id 字段为 数据 的唯一标识
7 return dataSource.firstIndex(where: { $0.id == viewController.id })
8}
9/// 通过下标索引获取 ViewController
10/// - Parameter index: 下标索引
11/// - Returns: ViewController
12private func viewControllerOf(Index index: Int) -> UIViewController? {
13 let viewControllers = UIViewController()
14 viewController.id = dataSource[index].id
15 return viewController
16}
协议代理
UIPageViewControllerDelegate
1//UIPageViewControllerDataSource
2/// 获取上一页的视图控制器
3func pageViewController(_ pageViewController: UIPageViewController, viewControllerBefore viewController: UIViewController) -> UIViewController? {
4 // 数据类型转换
5 guard let vc = viewController as? CustomViewController else { return nil }
6 // 获取上一页的下标索引
7 guard let index = indexOf(ViewController: vc) else { return nil }
8 // 索引校验,防止数据越界
9 if index <= 0 { return nil}
10 // 返回上一页的视图控制器
11 return viewControllerOf(Index: index - 1)
12}
13
14/// 获取下一页的视图控制器
15func pageViewController(_ pageViewController: UIPageViewController, viewControllerAfter viewController: UIViewController) -> UIViewController? {
16 // 数据类型转换
17 guard let vc = viewController as? CustomViewController else { return nil }
18 // 获取下一页的下标索引
19 guard let index = indexOf(ViewController: vc) else { return nil }
20 // 索引校验,防止数据越界
21 if index >= dataSource.count - 1 { return nil }
22 // 返回下一页的视图控制器
23 return viewControllerOf(Index: index + 1)
24}
25
26func presentationCount(for pageViewController: UIPageViewController) -> Int {
27 //返回 PageControl 中的数量,⚠️⚠️⚠️水平翻页模式下返回1将不会展示页面展示 PageControl
28 return 1
29}
30
31func presentationIndex(for pageViewController: UIPageViewController) -> Int {
32 //返回在 PageControl 中的选定项的索引
33 return 1
34}
手动翻页控制
1/// 下一页
2public func setupNextPage(){
3 /// 获取当前展示的视图控制器
4 guard let currentViewController = pageVC.viewControllers?.first else { return }
5 /// 获取下一页的视图控制器
6 guard let nextViewController = pageVC.dataSource?.pageViewController(pageVC, viewControllerAfter: currentViewController) else { return }
7 /// 设置下一页为当前显示的ViewController
8 pageVC.delegate?.pageViewController?(pageVC, willTransitionTo: [nextViewController])
9 pageVC.setViewControllers([nextViewController], direction: .forward, animated: true) { completed in
10 self.pageVC.delegate?.pageViewController?(self.pageVC, didFinishAnimating: true, previousViewControllers: [currentViewController], transitionCompleted: completed)
11}
12
13
14/// 上一页
15public func setupPrevPage(){
16 /// 获取当前展示的视图控制器
17 guard let currentViewController = pageVC.viewControllers?.first else { return }
18 /// 获取上一页的视图控制器
19 guard let prevViewController = pageVC.dataSource?.pageViewController(pageVC, viewControllerBefore: currentViewController) else { return }
20 /// 设置上一页为当前显示的ViewController
21 pageVC.delegate?.pageViewController?(pageVC, willTransitionTo: [prevViewController])
22 pageVC.setViewControllers([prevViewController], direction: .reverse, animated: true) { completed in
23 self.pageVC.delegate?.pageViewController?(self.pageVC, didFinishAnimating: true, previousViewControllers: [currentViewController], transitionCompleted: completed)
24}