Данная статья написана в развлекательных целях. Если вам интересно следить за самыми последними новостями iOS разработки и получать подборку интересных статей по этой тематике, тогда вам стоит подписаться на Телеграм-канал iOS Broadcast
Предположим, вам прилетела срочная задача: реализовать календарь, который ведет себя как физический перекидной календарь в котором на каждой странице 3 сентября.

Для начала сверстаем страницу календаря:
struct CalendarView: View { var body: some View { ZStack { VStack { ZStack { Text("Сентябрь") .foregroundColor(.red) .font(.system(.body)) } Text("3") .font(.largeTitle) } } .overlay( RoundedRectangle(cornerRadius: 20) .stroke(.black, lineWidth: 0.5) .frame(width: 100, height: 100) ) } }

Теперь добавим переворот страницы используя старый добрый UIPageViewController
lazy var pageViewController = UIPageViewController( transitionStyle: .pageCurl, navigationOrientation: .vertical ) override func viewDidLoad() { super.viewDidLoad() pageViewController.dataSource = self addChild(pageViewController) view.addSubview(pageViewController.view) pageViewController.setViewControllers([UIHostingController(rootView: CalendarView())], direction: .forward, animated: false) }
Для того чтобы сделать бесконечный календарь достаточно 2 инстансов CalendarView:
lazy var views: [UIViewController] = [ UIHostingController(rootView: CalendarView()), UIHostingController(rootView: CalendarView()), ] func pageViewController(_ pageViewController: UIPageViewController, viewControllerBefore viewController: UIViewController) -> UIViewController? { guard let index = views.firstIndex(of: viewController) else { return nil } return page(at: index - 1) } func pageViewController(_ pageViewController: UIPageViewController, viewControllerAfter viewController: UIViewController) -> UIViewController? { guard let index = views.firstIndex(of: viewController) else { return nil } return page(at: index + 1) } func page(at index: Int) -> UIViewController? { guard index > 0 else { return views.last } guard index < views.count else { return views.first } return views[index] }

Таким образом мы получаем зацикленный календарь который можно вечно переворачивать и видеть снова 3 сентября.
Полный листинг кода
import UIKit import SwiftUI struct CalendarView: View { var body: some View { ZStack { VStack { ZStack { Text("Сентябрь") .foregroundColor(.red) .bold() .font(.system(.body)) } Text("3") .font(.largeTitle) } } .overlay( RoundedRectangle(cornerRadius: 20) .stroke(.black, lineWidth: 0.5) .frame(width: 100, height: 100) ) } } class ViewController: UIViewController, UIPageViewControllerDataSource { lazy var pageViewController = UIPageViewController( transitionStyle: .pageCurl, navigationOrientation: .vertical ) lazy var views: [UIViewController] = [ UIHostingController(rootView: CalendarView()), UIHostingController(rootView: CalendarView()), ] override func viewDidLoad() { super.viewDidLoad() pageViewController.dataSource = self addChild(pageViewController) view.addSubview(pageViewController.view) pageViewController.setViewControllers([views.first!], direction: .forward, animated: false) } func pageViewController(_ pageViewController: UIPageViewController, viewControllerBefore viewController: UIViewController) -> UIViewController? { guard let index = views.firstIndex(of: viewController) else { return nil } return page(at: index - 1) } func pageViewController(_ pageViewController: UIPageViewController, viewControllerAfter viewController: UIViewController) -> UIViewController? { guard let index = views.firstIndex(of: viewController) else { return nil } return page(at: index + 1) } func page(at index: Int) -> UIViewController? { guard index > 0 else { return views.last } guard index < views.count else { return views.first } return views[index] } }

