Переворачиваем вечный SwiftUI календарь при помощи UIKit

—

от автора

Данная статья написана в развлекательных целях. Если вам интересно следить за самыми последними новостями 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]     } } 


ссылка на оригинал статьи https://habr.com/ru/articles/758470/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *