PageViewController.swift


  1. import SwiftUI
  2. import UIKit
  3. struct PageViewController<Page: View>: UIViewControllerRepresentable {
  4. var pages: [Page]
  5. func makeCoordinator() -> Coordinator {
  6. Coordinator(self)
  7. }
  8. func makeUIViewController(context: Context) -> UIPageViewController {
  9. let pageViewController = UIPageViewController(
  10. transitionStyle: .scroll,
  11. navigationOrientation: .horizontal)
  12. pageViewController.dataSource = context.coordinator
  13. return pageViewController
  14. }
  15. func updateUIViewController(_ pageViewController: UIPageViewController, context: Context) {
  16. pageViewController.setViewControllers(
  17. [context.coordinator.controllers[0]], direction: .forward, animated: true)
  18. }
  19. class Coordinator: NSObject, UIPageViewControllerDataSource {
  20. var parent: PageViewController
  21. var controllers = [UIViewController]()
  22. init(_ pageViewController: PageViewController) {
  23. parent = pageViewController
  24. controllers = parent.pages.map { UIHostingController(rootView: $0) }
  25. }
  26. func pageViewController(
  27. _ pageViewController: UIPageViewController,
  28. viewControllerBefore viewController: UIViewController) -> UIViewController?
  29. {
  30. guard let index = controllers.firstIndex(of: viewController) else {
  31. return nil
  32. }
  33. if index == 0 {
  34. return controllers.last
  35. }
  36. return controllers[index - 1]
  37. }
  38. func pageViewController(
  39. _ pageViewController: UIPageViewController,
  40. viewControllerAfter viewController: UIViewController) -> UIViewController?
  41. {
  42. guard let index = controllers.firstIndex(of: viewController) else {
  43. return nil
  44. }
  45. if index + 1 == controllers.count {
  46. return controllers.first
  47. }
  48. return controllers[index + 1]
  49. }
  50. }
  51. }