{"id":353814,"date":"2024-05-20T22:35:46","date_gmt":"2024-05-20T22:35:46","guid":{"rendered":"http:\/\/savepearlharbor.com\/?p=353814"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-29T21:00:00","slug":"","status":"publish","type":"post","link":"https:\/\/savepearlharbor.com\/?p=353814","title":{"rendered":"<span>\u041f\u0435\u0440\u0435\u0432\u043e\u0440\u0430\u0447\u0438\u0432\u0430\u0435\u043c \u0432\u0435\u0447\u043d\u044b\u0439 SwiftUI \u043a\u0430\u043b\u0435\u043d\u0434\u0430\u0440\u044c \u043f\u0440\u0438 \u043f\u043e\u043c\u043e\u0449\u0438 UIKit<\/span>"},"content":{"rendered":"<div><!--[--><!--]--><\/div>\n<div id=\"post-content-body\">\n<div>\n<div class=\"article-formatted-body article-formatted-body article-formatted-body_version-1\">\n<div xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\">\n<blockquote><p>\u0414\u0430\u043d\u043d\u0430\u044f \u0441\u0442\u0430\u0442\u044c\u044f \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u0430 \u0432 \u0440\u0430\u0437\u0432\u043b\u0435\u043a\u0430\u0442\u0435\u043b\u044c\u043d\u044b\u0445 \u0446\u0435\u043b\u044f\u0445. \u0415\u0441\u043b\u0438 \u0432\u0430\u043c \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u043e \u0441\u043b\u0435\u0434\u0438\u0442\u044c \u0437\u0430 \u0441\u0430\u043c\u044b\u043c\u0438 \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0438\u043c\u0438 \u043d\u043e\u0432\u043e\u0441\u0442\u044f\u043c\u0438 iOS \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u0438 \u043f\u043e\u043b\u0443\u0447\u0430\u0442\u044c \u043f\u043e\u0434\u0431\u043e\u0440\u043a\u0443 \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u044b\u0445 \u0441\u0442\u0430\u0442\u0435\u0439 \u043f\u043e \u044d\u0442\u043e\u0439 \u0442\u0435\u043c\u0430\u0442\u0438\u043a\u0435, \u0442\u043e\u0433\u0434\u0430 \u0432\u0430\u043c \u0441\u0442\u043e\u0438\u0442 \u043f\u043e\u0434\u043f\u0438\u0441\u0430\u0442\u044c\u0441\u044f \u043d\u0430\u00a0<a href=\"https:\/\/t.me\/ios_broadcast\">\u0422\u0435\u043b\u0435\u0433\u0440\u0430\u043c-\u043a\u0430\u043d\u0430\u043b iOS Broadcast<\/a><\/p><\/blockquote>\n<p>  \u041f\u0440\u0435\u0434\u043f\u043e\u043b\u043e\u0436\u0438\u043c, \u0432\u0430\u043c \u043f\u0440\u0438\u043b\u0435\u0442\u0435\u043b\u0430 \u0441\u0440\u043e\u0447\u043d\u0430\u044f \u0437\u0430\u0434\u0430\u0447\u0430: \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u0442\u044c \u043a\u0430\u043b\u0435\u043d\u0434\u0430\u0440\u044c, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0432\u0435\u0434\u0435\u0442 \u0441\u0435\u0431\u044f \u043a\u0430\u043a \u0444\u0438\u0437\u0438\u0447\u0435\u0441\u043a\u0438\u0439 \u043f\u0435\u0440\u0435\u043a\u0438\u0434\u043d\u043e\u0439 \u043a\u0430\u043b\u0435\u043d\u0434\u0430\u0440\u044c \u0432 \u043a\u043e\u0442\u043e\u0440\u043e\u043c \u043d\u0430 \u043a\u0430\u0436\u0434\u043e\u0439 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0435 3 \u0441\u0435\u043d\u0442\u044f\u0431\u0440\u044f.<br \/>  <img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w780q1\/webt\/gx\/z-\/9n\/gxz-9nfwy47vapdgb4ozwnmd5ua.jpeg\" data-src=\"https:\/\/habrastorage.org\/webt\/gx\/z-\/9n\/gxz-9nfwy47vapdgb4ozwnmd5ua.jpeg\" data-blurred=\"true\"\/><br \/>  <a name=\"habracut\"><\/a><br \/>  \u0414\u043b\u044f \u043d\u0430\u0447\u0430\u043b\u0430 \u0441\u0432\u0435\u0440\u0441\u0442\u0430\u0435\u043c \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0443 \u043a\u0430\u043b\u0435\u043d\u0434\u0430\u0440\u044f:  <\/p>\n<pre><code class=\"swift\">struct CalendarView: View {     var body: some View {         ZStack {             VStack {                 ZStack {                     Text(\"\u0421\u0435\u043d\u0442\u044f\u0431\u0440\u044c\")                         .foregroundColor(.red)                         .font(.system(.body))                 }                 Text(\"3\")                     .font(.largeTitle)             }         }         .overlay(             RoundedRectangle(cornerRadius: 20)                 .stroke(.black, lineWidth: 0.5)                 .frame(width: 100, height: 100)         )     } } <\/code><\/pre>\n<p>  <img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/webt\/qp\/od\/k4\/qpodk4nzj6rrmlgbao4rfdxuic4.png\" data-src=\"https:\/\/habrastorage.org\/webt\/qp\/od\/k4\/qpodk4nzj6rrmlgbao4rfdxuic4.png\"\/><br \/>  \u0422\u0435\u043f\u0435\u0440\u044c \u0434\u043e\u0431\u0430\u0432\u0438\u043c \u043f\u0435\u0440\u0435\u0432\u043e\u0440\u043e\u0442 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044f \u0441\u0442\u0430\u0440\u044b\u0439 \u0434\u043e\u0431\u0440\u044b\u0439 UIPageViewController  <\/p>\n<pre><code class=\"swift\">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) } <\/code><\/pre>\n<p>  \u0414\u043b\u044f \u0442\u043e\u0433\u043e \u0447\u0442\u043e\u0431\u044b \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0431\u0435\u0441\u043a\u043e\u043d\u0435\u0447\u043d\u044b\u0439 \u043a\u0430\u043b\u0435\u043d\u0434\u0430\u0440\u044c \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e 2 \u0438\u043d\u0441\u0442\u0430\u043d\u0441\u043e\u0432 CalendarView:  <\/p>\n<pre><code class=\"swift\">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 &lt; views.count else {         return views.first     }     return views[index] } <\/code><\/pre>\n<p>  <img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/webt\/lt\/_p\/5x\/lt_p5xbrg_62-tr0drrwigrsjuk.png\" data-src=\"https:\/\/habrastorage.org\/webt\/lt\/_p\/5x\/lt_p5xbrg_62-tr0drrwigrsjuk.png\"\/><br \/>  \u0422\u0430\u043a\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c \u043c\u044b \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u0437\u0430\u0446\u0438\u043a\u043b\u0435\u043d\u043d\u044b\u0439 \u043a\u0430\u043b\u0435\u043d\u0434\u0430\u0440\u044c \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043c\u043e\u0436\u043d\u043e \u0432\u0435\u0447\u043d\u043e \u043f\u0435\u0440\u0435\u0432\u043e\u0440\u0430\u0447\u0438\u0432\u0430\u0442\u044c \u0438 \u0432\u0438\u0434\u0435\u0442\u044c \u0441\u043d\u043e\u0432\u0430 3 \u0441\u0435\u043d\u0442\u044f\u0431\u0440\u044f.<\/p>\n<div class=\"spoiler\" role=\"button\" tabindex=\"0\">                         <b class=\"spoiler_title\">\u041f\u043e\u043b\u043d\u044b\u0439 \u043b\u0438\u0441\u0442\u0438\u043d\u0433 \u043a\u043e\u0434\u0430<\/b>                         <\/p>\n<div class=\"spoiler_text\">\n<pre><code class=\"swift\">import UIKit import SwiftUI  struct CalendarView: View {     var body: some View {         ZStack {             VStack {                 ZStack {                     Text(\"\u0421\u0435\u043d\u0442\u044f\u0431\u0440\u044c\")                         .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 &lt; views.count else {             return views.first         }         return views[index]     } } <\/code><\/pre>\n<p>  <\/div>\n<\/p><\/div>\n<\/div>\n<\/div>\n<\/div>\n<p><!----><!----><\/div>\n<p><!----><!----><br \/> \u0441\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b \u0441\u0442\u0430\u0442\u044c\u0438 <a href=\"https:\/\/habr.com\/ru\/articles\/758470\/\"> https:\/\/habr.com\/ru\/articles\/758470\/<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<div><!--[--><!--]--><\/div>\n<div id=\"post-content-body\">\n<div>\n<div class=\"article-formatted-body article-formatted-body article-formatted-body_version-1\">\n<div xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\">\n<blockquote><p>\u0414\u0430\u043d\u043d\u0430\u044f \u0441\u0442\u0430\u0442\u044c\u044f \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u0430 \u0432 \u0440\u0430\u0437\u0432\u043b\u0435\u043a\u0430\u0442\u0435\u043b\u044c\u043d\u044b\u0445 \u0446\u0435\u043b\u044f\u0445. \u0415\u0441\u043b\u0438 \u0432\u0430\u043c \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u043e \u0441\u043b\u0435\u0434\u0438\u0442\u044c \u0437\u0430 \u0441\u0430\u043c\u044b\u043c\u0438 \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0438\u043c\u0438 \u043d\u043e\u0432\u043e\u0441\u0442\u044f\u043c\u0438 iOS \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u0438 \u043f\u043e\u043b\u0443\u0447\u0430\u0442\u044c \u043f\u043e\u0434\u0431\u043e\u0440\u043a\u0443 \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u044b\u0445 \u0441\u0442\u0430\u0442\u0435\u0439 \u043f\u043e \u044d\u0442\u043e\u0439 \u0442\u0435\u043c\u0430\u0442\u0438\u043a\u0435, \u0442\u043e\u0433\u0434\u0430 \u0432\u0430\u043c \u0441\u0442\u043e\u0438\u0442 \u043f\u043e\u0434\u043f\u0438\u0441\u0430\u0442\u044c\u0441\u044f \u043d\u0430\u00a0<a href=\"https:\/\/t.me\/ios_broadcast\">\u0422\u0435\u043b\u0435\u0433\u0440\u0430\u043c-\u043a\u0430\u043d\u0430\u043b iOS Broadcast<\/a><\/p><\/blockquote>\n<p>  \u041f\u0440\u0435\u0434\u043f\u043e\u043b\u043e\u0436\u0438\u043c, \u0432\u0430\u043c \u043f\u0440\u0438\u043b\u0435\u0442\u0435\u043b\u0430 \u0441\u0440\u043e\u0447\u043d\u0430\u044f \u0437\u0430\u0434\u0430\u0447\u0430: \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u0442\u044c \u043a\u0430\u043b\u0435\u043d\u0434\u0430\u0440\u044c, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0432\u0435\u0434\u0435\u0442 \u0441\u0435\u0431\u044f \u043a\u0430\u043a \u0444\u0438\u0437\u0438\u0447\u0435\u0441\u043a\u0438\u0439 \u043f\u0435\u0440\u0435\u043a\u0438\u0434\u043d\u043e\u0439 \u043a\u0430\u043b\u0435\u043d\u0434\u0430\u0440\u044c \u0432 \u043a\u043e\u0442\u043e\u0440\u043e\u043c \u043d\u0430 \u043a\u0430\u0436\u0434\u043e\u0439 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0435 3 \u0441\u0435\u043d\u0442\u044f\u0431\u0440\u044f.<br \/>  <img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w780q1\/webt\/gx\/z-\/9n\/gxz-9nfwy47vapdgb4ozwnmd5ua.jpeg\" data-src=\"https:\/\/habrastorage.org\/webt\/gx\/z-\/9n\/gxz-9nfwy47vapdgb4ozwnmd5ua.jpeg\" data-blurred=\"true\"\/>  <\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[],"tags":[],"class_list":["post-353814","post","type-post","status-publish","format-standard","hentry"],"_links":{"self":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/353814","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=353814"}],"version-history":[{"count":0,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/353814\/revisions"}],"wp:attachment":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=353814"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=353814"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=353814"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}