{"id":360699,"date":"2024-05-21T00:58:21","date_gmt":"2024-05-21T00:58:21","guid":{"rendered":"http:\/\/savepearlharbor.com\/?p=360699"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-29T21:00:00","slug":"","status":"publish","type":"post","link":"https:\/\/savepearlharbor.com\/?p=360699","title":{"rendered":"<span>DebugMenu \u0438 \u0432\u0438\u0437\u0443\u0430\u043b\u044c\u043d\u0430\u044f \u0438\u0435\u0440\u0430\u0440\u0445\u0438\u044f \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u043e\u0432 \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u0430<\/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-2\">\n<div xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\">\n<p><strong>\u041f\u0440\u0438\u043c\u0435\u0447\u0430\u043d\u0438\u0435<\/strong>. \u042d\u0442\u0430 \u0441\u0442\u0430\u0442\u044c\u044f \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0434\u043e\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u0435\u043c \u043a \u0441\u0442\u0430\u0442\u044c\u0435 <a href=\"https:\/\/habr.com\/ru\/companies\/alfa\/articles\/763596\/\">\u0414\u0435\u0431\u0430\u0433\u0433\u0438\u043d\u0433 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u0431\u0435\u0437 Xcode. \u0417\u0430\u0447\u0435\u043c?<\/a><\/p>\n<p>\u0412 \u043d\u0430\u0447\u0430\u043b\u0435 \u043a\u0432\u0430\u0440\u0442\u0430\u043b\u0430, \u0432 \u0410\u043b\u044c\u0444\u0435, \u043c\u044b \u0432\u044b\u0431\u0438\u0440\u0430\u0435\u043c \u0441\u0435\u0431\u0435 \u0442\u0435\u0445\u043d\u0438\u0447\u0435\u0441\u043a\u0438\u0435 \u0442\u0430\u0441\u043a\u0438 \u2014 \u0437\u0430\u0434\u0430\u0447\u0438, \u043d\u0430\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u043d\u044b\u0435 \u043d\u0430 \u0442\u0435\u0445\u043d\u0438\u0447\u0435\u0441\u043a\u043e\u0435 \u0440\u0430\u0437\u0432\u0438\u0442\u0438\u0435 \u043f\u0440\u043e\u0435\u043a\u0442\u0430, \u0430 \u043d\u0435 \u043d\u0430 \u043f\u0440\u043e\u0434\u0443\u043a\u0442\u043e\u0432\u0443\u044e \u0441\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u044e\u0449\u0443\u044e. \u041f\u0440\u0438 \u0432\u044b\u0431\u043e\u0440\u0435 \u0437\u0430\u0434\u0430\u0447\u0438 \u0445\u043e\u0447\u0435\u0442\u0441\u044f, \u0447\u0442\u043e\u0431\u044b \u043e\u043d\u0430 \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u043e\u0432\u0430\u043b\u0430 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u0438\u043c \u0443\u0441\u043b\u043e\u0432\u0438\u044f\u043c:<\/p>\n<ul>\n<li>\n<p>\u0440\u0435\u0448\u0430\u0435\u0442 \u0440\u0435\u0430\u043b\u044c\u043d\u044b\u0435 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u044b \u043d\u0430\u0448\u0435\u0439 \u043a\u043e\u043c\u0430\u043d\u0434\u044b, \u0443\u043f\u0440\u043e\u0449\u0430\u044f \u0435\u0436\u0435\u0434\u043d\u0435\u0432\u043d\u0443\u044e \u0440\u0430\u0431\u043e\u0442\u0443;<\/p>\n<\/li>\n<li>\n<p>\u0443\u043a\u043b\u0430\u0434\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u0432 \u0447\u0435\u0442\u044b\u0440\u0435 \u0432\u044b\u0434\u0435\u043b\u0435\u043d\u043d\u044b\u0445 \u0442\u0435\u0445\u043d\u0438\u0447\u0435\u0441\u043a\u0438\u0445 \u0434\u043d\u044f \u2014 \u043d\u0430\u0448 \u0444\u043e\u0440\u043c\u0430\u0442 \u0440\u0430\u0431\u043e\u0442\u044b \u043f\u0440\u0435\u0434\u043f\u043e\u043b\u0430\u0433\u0430\u0435\u0442 \u0432\u044b\u0431\u043e\u0440 \u0442\u0440\u0435\u0445 \u0437\u0430\u0434\u0430\u0447 \u043d\u0430 \u043a\u0432\u0430\u0440\u0442\u0430\u043b \u0438 \u0438\u0445 \u0440\u0435\u0448\u0435\u043d\u0438\u0435 \u0432 \u0442\u0435\u0447\u0435\u043d\u0438\u0435 20% \u0440\u0430\u0431\u043e\u0447\u0435\u0433\u043e \u0432\u0440\u0435\u043c\u0435\u043d\u0438;<\/p>\n<\/li>\n<li>\n<p>\u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u0440\u0430\u0441\u0442\u0438 \u043f\u0440\u043e\u0444\u0435\u0441\u0441\u0438\u043e\u043d\u0430\u043b\u044c\u043d\u043e, \u0434\u0430\u0432\u0430\u044f \u0448\u0430\u043d\u0441 \u043f\u043e\u0433\u0440\u0443\u0437\u0438\u0442\u044c\u0441\u044f \u0432 \u043d\u043e\u0432\u044b\u0435 \u0442\u0435\u0445\u043d\u043e\u043b\u043e\u0433\u0438\u0438 \u0438 \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u044b.<\/p>\n<\/li>\n<\/ul>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/fd2\/f1b\/b68\/fd2f1bb6897dba2e28f784b36512e4c7.png\" width=\"1568\" height=\"862\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/fd2\/f1b\/b68\/fd2f1bb6897dba2e28f784b36512e4c7.png\"\/><\/figure>\n<p>\u0421\u0440\u0435\u0434\u0438 \u0442\u0435\u0445\u043d\u0438\u0447\u0435\u0441\u043a\u0438\u0445 \u0437\u0430\u0434\u0430\u0447 \u043c\u043e\u0435 \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u0435 \u043f\u0440\u0438\u0432\u043b\u0435\u043a\u043b\u0430 \u0437\u0430\u0434\u0430\u0447\u0430 \u043f\u043e \u0432\u0438\u0437\u0443\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u0438\u0435\u0440\u0430\u0440\u0445\u0438\u0438 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u043e\u0432 \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u0430. \u041e\u043d\u0430 \u043a\u0430\u0437\u0430\u043b\u0430\u0441\u044c \u043c\u043d\u0435 \u0438\u0434\u0435\u0430\u043b\u044c\u043d\u043e\u0439: \u043f\u043e\u043c\u0438\u043c\u043e \u043e\u0447\u0435\u0432\u0438\u0434\u043d\u043e\u0439 \u043f\u043e\u043b\u044c\u0437\u044b \u0434\u043b\u044f \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u043e\u0432, \u043a\u043e\u0442\u043e\u0440\u044b\u043c \u043d\u0435 \u0432\u0441\u0435\u0433\u0434\u0430 \u0443\u0434\u043e\u0431\u043d\u043e \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u0441 View Hierarchy \u0432 Xcode (\u0432 \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u0441\u043b\u0443\u0447\u0430\u044f\u0445, \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044f \u0443 \u0432\u044c\u044e \u043e\u0442\u0441\u0443\u0442\u0441\u0442\u0432\u0443\u044e\u0442), \u0438 \u043d\u0435\u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e \u043f\u0440\u0438 \u0441\u0431\u043e\u0440\u043a\u0430\u0445 \u0447\u0435\u0440\u0435\u0437 AppCenter \u0438\u043b\u0438 TestFlight, \u0437\u0430\u0434\u0430\u0447\u0430 \u043e\u0431\u0435\u0449\u0430\u043b\u0430 \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u044b\u0435 \u0432\u044b\u0437\u043e\u0432\u044b \u2014 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u043f\u043e\u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u0441 SceneKit. \u041a \u0442\u043e\u043c\u0443 \u0436\u0435, \u043d\u0430\u043b\u0438\u0447\u0438\u0435 \u043e\u0442\u043a\u0440\u044b\u0442\u044b\u0445 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a, \u0440\u0435\u0448\u0430\u044e\u0449\u0438\u0445 \u043f\u043e\u0434\u043e\u0431\u043d\u044b\u0435 \u0437\u0430\u0434\u0430\u0447\u0438, \u043f\u0440\u0435\u0434\u043f\u043e\u043b\u0430\u0433\u0430\u043b\u043e \u043b\u0435\u0433\u043a\u043e\u0441\u0442\u044c \u0438\u043d\u0442\u0435\u0433\u0440\u0430\u0446\u0438\u0438 \u0432 \u043d\u0430\u0448 \u043f\u0440\u043e\u0435\u043a\u0442.<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/964\/de4\/fc6\/964de4fc61e9efe37e2cdcb283e8ba4e.png\" alt=\"\u0413\u043b\u0430\u0432\u043d\u044b\u0439 \u044d\u043a\u0440\u0430\u043d \u0432\u043e View Hierarchy\" title=\"\u0413\u043b\u0430\u0432\u043d\u044b\u0439 \u044d\u043a\u0440\u0430\u043d \u0432\u043e View Hierarchy\" width=\"1978\" height=\"1604\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/964\/de4\/fc6\/964de4fc61e9efe37e2cdcb283e8ba4e.png\"\/><\/p>\n<div><figcaption>\u0413\u043b\u0430\u0432\u043d\u044b\u0439 \u044d\u043a\u0440\u0430\u043d \u0432\u043e View Hierarchy<\/figcaption><\/div>\n<\/figure>\n<p>\u041e\u0434\u043d\u0430\u043a\u043e, \u043a\u0430\u043a \u0447\u0430\u0441\u0442\u043e \u0431\u044b\u0432\u0430\u0435\u0442 \u0432 \u043c\u0438\u0440\u0435 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0438, \u043f\u0435\u0440\u0432\u043e\u043d\u0430\u0447\u0430\u043b\u044c\u043d\u044b\u0435 \u043e\u0436\u0438\u0434\u0430\u043d\u0438\u044f \u0440\u0430\u0437\u043e\u0448\u043b\u0438\u0441\u044c \u0441 \u0440\u0435\u0430\u043b\u044c\u043d\u043e\u0441\u0442\u044c\u044e. \u0412 \u044d\u0442\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0435 \u044f \u0445\u043e\u0447\u0443 \u043f\u043e\u0434\u0435\u043b\u0438\u0442\u044c\u0441\u044f \u043e\u043f\u044b\u0442\u043e\u043c, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043f\u043e\u043b\u0443\u0447\u0438\u043b, \u0440\u0430\u0437\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u044f \u0438 \u0432\u043d\u0435\u0434\u0440\u044f\u044f \u044d\u0442\u0443 \u0444\u0438\u0447\u0443, \u0440\u0430\u0441\u0441\u043a\u0430\u0437\u0430\u0442\u044c \u043e \u0442\u0435\u0445\u043d\u0438\u0447\u0435\u0441\u043a\u0438\u0445 \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u043e\u0441\u0442\u044f\u0445 \u0438 \u043e \u0442\u043e\u043c, \u043f\u043e\u0447\u0435\u043c\u0443 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435 \u043e\u0442\u0440\u044b\u0442\u044b\u0445 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a \u043c\u043e\u0436\u0435\u0442 \u043e\u043a\u0430\u0437\u0430\u0442\u044c\u0441\u044f \u043d\u0435 \u0441\u0430\u043c\u044b\u043c \u043f\u0440\u043e\u0441\u0442\u044b\u043c \u0434\u0435\u043b\u043e\u043c.<\/p>\n<h2>\u0418\u0437\u0443\u0447\u0430\u0435\u043c \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u0435 \u0440\u0435\u0448\u0435\u043d\u0438\u044f<\/h2>\n<p>\u041d\u0430\u0447\u0430\u043b \u044f \u0441 \u0438\u0437\u0443\u0447\u0435\u043d\u0438\u044f \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u0445 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a \u0438 \u043e\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u043b\u0441\u044f \u043d\u0430:<\/p>\n<ul>\n<li>\n<p><a href=\"https:\/\/github.com\/FLEXTool\/FLEX\">Flex<\/a> \u2014 \u043d\u0430\u0432\u0435\u0440\u043d\u043e\u0435, \u0441\u0430\u043c\u0430\u044f \u043f\u043e\u043f\u0443\u043b\u044f\u0440\u043d\u0430\u044f \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0430 \u0434\u043b\u044f \u0434\u0435\u0431\u0430\u0433\u0430 \u043d\u0430 iOS.<\/p>\n<\/li>\n<li>\n<p><a href=\"https:\/\/github.com\/indragiek\/InAppViewDebugger\">InAppViewDebugger<\/a> \u2014 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0430 \u043a\u0430\u043a \u0440\u0430\u0437 \u043f\u0440\u043e \u043c\u043e\u044e \u0444\u0438\u0447\u0443: \u043c\u043d\u043e\u0433\u043e \u0437\u0432\u0435\u0437\u0434\u043e\u0447\u0435\u043a \u043d\u0430 GitHub, \u0438 \u0432 Readme Flex-\u0430 \u0433\u043e\u0432\u043e\u0440\u0438\u0442\u0441\u044f \u043e \u043d\u0435\u0439, \u043a\u0430\u043a \u043e\u0431 \u043e\u0434\u043d\u043e\u043c \u0438\u0437 \u0440\u0435\u0444\u0435\u0440\u0435\u043d\u0441\u043e\u0432.<\/p>\n<\/li>\n<li>\n<p><a href=\"https:\/\/github.com\/nikitabelopotapov\/Glance\">Glance<\/a> \u2014 \u043d\u0435 \u0442\u0430\u043a\u0430\u044f \u043f\u043e\u043f\u0443\u043b\u044f\u0440\u043d\u0430\u044f \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0430, \u043d\u043e \u0441\u043e \u0441\u0445\u043e\u0436\u0438\u043c \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b\u043e\u043c.<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/6a3\/f63\/0d6\/6a3f630d6a080c867cac5d19b483628f.png\" alt=\"\u041e\u0436\u0438\u0434\u0430\u0435\u043c\u044b\u0439 \u043f\u043b\u0430\u043d \u0440\u0430\u0431\u043e\u0442\" title=\"\u041e\u0436\u0438\u0434\u0430\u0435\u043c\u044b\u0439 \u043f\u043b\u0430\u043d \u0440\u0430\u0431\u043e\u0442\" width=\"1600\" height=\"1069\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/6a3\/f63\/0d6\/6a3f630d6a080c867cac5d19b483628f.png\"\/><\/p>\n<div><figcaption>\u041e\u0436\u0438\u0434\u0430\u0435\u043c\u044b\u0439 \u043f\u043b\u0430\u043d \u0440\u0430\u0431\u043e\u0442<\/figcaption><\/div>\n<\/figure>\n<\/li>\n<\/ul>\n<p>\u041d\u043e \u043f\u0440\u0435\u0434\u0432\u0430\u0440\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u0440\u0435\u0448\u0438\u043b \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0438\u0442\u044c \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438 \u043a \u043d\u0430\u0448\u0435\u043c\u0443 \u043f\u0440\u043e\u0435\u043a\u0442\u0443 \u0438 \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c, \u043a\u0430\u043a \u043e\u043d\u0438 \u0431\u0443\u0434\u0443\u0442 \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c. \u0418 \u0442\u0443\u0442 \u043c\u0435\u043d\u044f \u0436\u0434\u0430\u043b\u0438 \u043d\u0435\u043f\u0440\u0438\u044f\u0442\u043d\u044b\u0435 \u0441\u044e\u0440\u043f\u0440\u0438\u0437\u044b.<\/p>\n<p>\u041f\u043e\u043f\u0440\u043e\u0431\u043e\u0432\u0430\u043b \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u044c Flex \u043d\u0430 \u0433\u043b\u0430\u0432\u043d\u043e\u043c \u044d\u043a\u0440\u0430\u043d\u0435 \u0438 \u0443\u0432\u0438\u0434\u0435\u043b \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u043c\u043d\u043e\u0433\u043e \u043d\u0435\u043f\u0440\u0438\u044f\u0442\u043d\u044b\u0445 \u043c\u043e\u043c\u0435\u043d\u0442\u043e\u0432. <\/p>\n<ul>\n<li>\n<p>\u0412\u043e-\u043f\u0435\u0440\u0432\u044b\u0445, \u0432\u044c\u044e\u0448\u043a\u0438 \u043d\u0435 \u043e\u0431\u0440\u0435\u0437\u0430\u044e\u0442\u0441\u044f \u043f\u043e \u043e\u0431\u043b\u0430\u0441\u0442\u0438 \u0432\u0438\u0434\u0438\u043c\u043e\u0441\u0442\u0438, \u0447\u0442\u043e, \u043a\u0430\u043a \u043c\u043d\u0435 \u043f\u043e\u043a\u0430\u0437\u0430\u043b\u043e\u0441\u044c, \u043d\u0430\u043c \u043d\u0435 \u043f\u043e\u0434\u0445\u043e\u0434\u0438\u0442. <\/p>\n<\/li>\n<li>\n<p>\u0412\u043e-\u0432\u0442\u043e\u0440\u044b\u0445 \u2014 \u043c\u043d\u043e\u0436\u0435\u0441\u0442\u0432\u043e \u0430\u0440\u0442\u0435\u0444\u0430\u043a\u0442\u043e\u0432. \u0412 \u043e\u0431\u0449\u0435\u043c \u0438 \u0446\u0435\u043b\u043e\u043c \u0432\u0438\u0434\u043d\u043e, \u0447\u0442\u043e \u0432\u0441\u0451 \u043d\u0435 \u043e\u0447\u0435\u043d\u044c \u0445\u043e\u0440\u043e\u0448\u043e. <\/p>\n<\/li>\n<li>\n<p>\u0418, \u0432-\u0442\u0440\u0435\u0442\u044c\u0438\u0445, \u0431\u0430\u0440\u0430\u0431\u0430\u043d\u043d\u0430\u044f \u0434\u0440\u043e\u0431\u044c\u2026 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u043a\u0440\u0430\u0448\u0438\u0442\u0441\u044f!<\/p>\n<\/li>\n<\/ul>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/bf2\/9a3\/3f0\/bf29a33f09fe3d2d5dbacaa41a3cb79d.png\" alt=\"\u0410\u0440\u0442\u0435\u0444\u0430\u043a\u0442\u044b \u0432\u043e Flex\" title=\"\u0410\u0440\u0442\u0435\u0444\u0430\u043a\u0442\u044b \u0432\u043e Flex\" width=\"1600\" height=\"544\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/bf2\/9a3\/3f0\/bf29a33f09fe3d2d5dbacaa41a3cb79d.png\"\/><\/p>\n<div><figcaption>\u0410\u0440\u0442\u0435\u0444\u0430\u043a\u0442\u044b \u0432\u043e Flex<\/figcaption><\/div>\n<\/figure>\n<p>\u041f\u0440\u043e\u0431\u044b \u043e\u0441\u0442\u0430\u0432\u0448\u0438\u0445\u0441\u044f \u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a\u043e\u0432 \u0442\u043e\u0436\u0435 \u0431\u044b\u043b\u0438 \u043d\u0435\u0443\u0442\u0435\u0448\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u043c\u0438. InAppViewDebugger \u0442\u0430\u043a\u0436\u0435 \u0438\u043c\u0435\u043b \u043c\u043d\u043e\u0436\u0435\u0441\u0442\u0432\u043e \u0430\u0440\u0442\u0435\u0444\u0430\u043a\u0442\u043e\u0432 \u0438 \u043a\u0440\u0430\u0448\u0438\u043b\u0441\u044f, \u0430 Glance \u0445\u043e\u0442\u044c \u0438 \u043d\u0435 \u043f\u0430\u0434\u0430\u043b, \u043d\u043e \u043e\u0431\u0440\u0435\u0437\u0430\u043b \u0432\u044c\u044e\u0448\u043a\u0438 \u0438 \u0442\u0430\u043a\u0436\u0435 \u0438\u043c\u0435\u043b \u0430\u0440\u0442\u0435\u0444\u0430\u043a\u0442\u044b.<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/05d\/559\/c5b\/05d559c5b4800ad6de58e748e125b36b.png\" alt=\"\u0410\u0440\u0442\u0435\u0444\u0430\u043a\u0442\u044b \u0432 InAppViewDebugger \u0438 Glance\" title=\"\u0410\u0440\u0442\u0435\u0444\u0430\u043a\u0442\u044b \u0432 InAppViewDebugger \u0438 Glance\" width=\"1266\" height=\"1098\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/05d\/559\/c5b\/05d559c5b4800ad6de58e748e125b36b.png\"\/><\/p>\n<div><figcaption>\u0410\u0440\u0442\u0435\u0444\u0430\u043a\u0442\u044b \u0432 InAppViewDebugger \u0438 Glance<\/figcaption><\/div>\n<\/figure>\n<figure class=\"float full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/bd2\/1b1\/b08\/bd21b1b0822ad95f3651e32500da3f1d.png\" alt=\"\" title=\"\" width=\"720\" height=\"720\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/bd2\/1b1\/b08\/bd21b1b0822ad95f3651e32500da3f1d.png\"\/><\/figure>\n<p>\u0418 \u0442\u0443\u0442 \u044f \u043f\u043e\u043d\u0438\u043c\u0430\u044e, \u0447\u0442\u043e \u044d\u0442\u043e \u0443\u0436\u0435 \u043d\u0435 \u043b\u0435\u0433\u043a\u0430\u044f \u043f\u0440\u043e\u0433\u0443\u043b\u043a\u0430 \u0438 \u0431\u044b\u0441\u0442\u0440\u043e \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u043d\u0438\u0447\u0435\u0433\u043e \u043d\u0435 \u0432\u044b\u0439\u0434\u0435\u0442. \u041f\u0440\u0438\u0434\u0435\u0442\u0441\u044f \u043f\u043e\u0432\u043e\u0437\u0438\u0442\u044c\u0441\u044f. <\/p>\n<h2>View \u0441\u043b\u043e\u0439<\/h2>\n<p>\u0420\u0435\u0448\u0438\u043b \u043f\u043e\u0439\u0442\u0438 \u043e\u0442 \u043f\u0440\u043e\u0441\u0442\u043e\u0433\u043e \u043a \u0441\u043b\u043e\u0436\u043d\u043e\u043c\u0443 \u0438 \u043d\u0430\u0447\u0430\u0442\u044c \u0440\u0430\u0431\u043e\u0442\u044b \u0441 \u0432\u044c\u044e \u0441\u043b\u043e\u044f \u2014 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438 \u043d\u0435 \u0438\u043c\u0435\u043b\u0438 \u043f\u0440\u043e\u0431\u043b\u0435\u043c \u0441 \u043d\u0438\u043c \u0438 \u0440\u0435\u0448\u0435\u043d\u0438\u0435 \u0442\u0443\u0442 \u043f\u043e\u0437\u0430\u0438\u043c\u0441\u0442\u0432\u043e\u0432\u0430\u043d\u043e. \u0414\u043b\u044f \u043d\u0435\u0433\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c SceneKit.<\/p>\n<p><a href=\"https:\/\/developer.apple.com\/documentation\/scenekit\/\">SceneKit<\/a> \u2014 \u044d\u0442\u043e \u0432\u044b\u0441\u043e\u043a\u043e\u0443\u0440\u043e\u0432\u043d\u0435\u0432\u044b\u0439 \u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a \u0434\u043b\u044f 3D-\u0433\u0440\u0430\u0444\u0438\u043a\u0438, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u043d\u0430\u043c \u0441\u043e\u0437\u0434\u0430\u0432\u0430\u0442\u044c 3D \u0441\u0446\u0435\u043d\u044b. \u0420\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u043f\u043e\u0432\u0435\u0440\u0445 Metal-\u0430 \u0438 \u0435\u0433\u043e \u043f\u0440\u0435\u0438\u043c\u0443\u0449\u0435\u0441\u0442\u0432\u0430 \u043f\u0435\u0440\u0435\u0434 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435\u043c \u0432 \u043f\u0435\u0440\u0432\u043e\u0437\u0434\u0430\u043d\u043d\u043e\u043c \u0432\u0438\u0434\u0435 \u0437\u0430\u043a\u043b\u044e\u0447\u0430\u0435\u0442\u0441\u044f \u0432 \u043f\u0440\u043e\u0441\u0442\u043e\u0442\u0435 \u2014 \u043d\u0435 \u043d\u0443\u0436\u043d\u043e \u043f\u043e\u0433\u0440\u0443\u0436\u0430\u0442\u044c\u0441\u044f \u043d\u0438 \u0432 \u043a\u0430\u043a\u0438\u0435 \u043d\u0438\u0437\u043a\u043e\u0443\u0440\u043e\u0432\u043d\u0435\u0432\u044b\u0435 API, \u0432\u0441\u0451 \u043f\u0440\u0435\u0434\u0435\u043b\u044c\u043d\u043e \u0443\u043f\u0440\u043e\u0449\u0435\u043d\u043e \u0438 \u043f\u043e\u043d\u044f\u0442\u043d\u043e.<\/p>\n<details class=\"spoiler\">\n<summary>\u041d\u0435\u0431\u043e\u043b\u044c\u0448\u0430\u044f \u0438\u0441\u0442\u043e\u0440\u0438\u0447\u0435\u0441\u043a\u0430\u044f \u0441\u043f\u0440\u0430\u0432\u043a\u0430:<\/summary>\n<div class=\"spoiler__content\">\n<ul>\n<li>\n<p>SceneKit \u0431\u044b\u043b \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d \u043d\u0430 macOS \u0432 2012.<\/p>\n<\/li>\n<li>\n<p>\u0412 2014 Apple \u043f\u043e\u0440\u0442\u0438\u0440\u043e\u0432\u0430\u043b\u0438 \u0435\u0433\u043e \u043d\u0430 iOS.<\/p>\n<\/li>\n<li>\n<p>\u041a \u043c\u043e\u043c\u0435\u043d\u0442\u0443 \u0430\u043d\u043e\u043d\u0441\u0430 ARKit-\u0430 \u0432 2017 \u0431\u044b\u043b \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u0440\u0430\u0437\u0432\u0438\u0442 \u0434\u043b\u044f \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f \u0438\u0445 \u0432 \u043f\u0430\u0440\u0435.<\/p>\n<\/li>\n<\/ul>\n<\/div>\n<\/details>\n<p>\u0418\u0442\u0430\u043a, \u043d\u0430\u0447\u043d\u0435\u043c \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0443 \u043d\u0430\u0448\u0435\u0439 \u0432\u044c\u044e.<\/p>\n<p><strong>\u041f\u0435\u0440\u0432\u043e\u0435, \u0447\u0442\u043e \u043d\u0430\u0434\u043e \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u2014 \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u044d\u043a\u0437\u0435\u043c\u043f\u043b\u044f\u0440\u044b SCNScene \u0438\u00a0SCNView.<\/strong><\/p>\n<pre><code class=\"swift\">private let sceneView = SCNView() private let scene = SCNScene() ... addSubview(sceneView) ... sceneView.allowsCameraControl = true sceneView.scene = scene<\/code><\/pre>\n<p>\u0412\u0441\u0451, \u0447\u0442\u043e \u043d\u0430\u0445\u043e\u0434\u0438\u0442\u0441\u044f \u0432 \u0432\u0438\u0440\u0442\u0443\u0430\u043b\u044c\u043d\u044b\u043c \u043f\u0440\u043e\u0441\u0442\u0440\u0430\u043d\u0441\u0442\u0432\u0435, \u043d\u0430\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u0441\u0446\u0435\u043d\u043e\u0439, \u0438 \u0437\u0430 \u043d\u0435\u0451 \u043e\u0442\u0432\u0435\u0447\u0430\u0435\u0442 \u043a\u043b\u0430\u0441\u0441 <a href=\"https:\/\/developer.apple.com\/documentation\/scenekit\/scnscene\">SCNScene<\/a>.<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/4e7\/20e\/715\/4e720e715584310378cd816286ee62b1.png\" width=\"1600\" height=\"640\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/4e7\/20e\/715\/4e720e715584310378cd816286ee62b1.png\"\/><\/figure>\n<p><a href=\"https:\/\/developer.apple.com\/documentation\/scenekit\/scnview\">SCNView<\/a> \u2014 \u044d\u0442\u043e \u0432\u044c\u044e\u0448\u043a\u0430, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u043c\u043e\u0436\u0435\u0442 \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u0441\u043e \u0441\u0446\u0435\u043d\u043e\u0439. \u0414\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c \u0435\u0451 \u0432 \u0438\u0435\u0440\u0430\u0440\u0445\u0438\u044e \u0438 \u0432\u043a\u043b\u044e\u0447\u0430\u0435\u043c \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440 <code>allowsCameraControl<\/code> \u2014 \u043e\u043d \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u043c\u0435\u043d\u044f\u0442\u044c \u043f\u043e\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u043a\u0430\u043c\u0435\u0440\u044b \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u0436\u0435\u0441\u0442\u043e\u0432 \u2014\u00a0\u0438 \u043f\u0440\u0438\u0441\u0432\u0430\u0438\u0432\u0430\u0435\u043c \u044d\u043a\u0437\u0435\u043c\u043f\u043b\u044f\u0440 \u0441\u0446\u0435\u043d\u044b \u0432\u043e \u0432\u044c\u044e.<\/p>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u043d\u0430\u0441\u0442\u0440\u043e\u0438\u043c \u043d\u043e\u0434\u0443 \u043a\u0430\u043c\u0435\u0440\u044b. <\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/c9d\/75a\/2c0\/c9d75a2c074f5cc1f30910b2345b05c6.png\" width=\"1155\" height=\"723\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/c9d\/75a\/2c0\/c9d75a2c074f5cc1f30910b2345b05c6.png\"\/><\/figure>\n<p><a href=\"https:\/\/developer.apple.com\/documentation\/scenekit\/scnnode\">SCNNode<\/a> \u2014 \u044d\u0442\u043e \u043e\u0441\u043d\u043e\u0432\u043d\u043e\u0439 \u044d\u043b\u0435\u043c\u0435\u043d\u0442 \u0433\u0440\u0430\u0444\u0430 \u0441\u0446\u0435\u043d\u044b, \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u044f\u044e\u0449\u0438\u0439 \u043f\u043e\u0437\u0438\u0446\u0438\u044e \u0438 \u0442\u0440\u0430\u043d\u0441\u0444\u043e\u0440\u043c\u044b \u0432 \u0442\u0440\u0435\u0445\u043c\u0435\u0440\u043d\u043e\u043c \u043f\u0440\u043e\u0441\u0442\u0440\u0430\u043d\u0441\u0442\u0432\u0435, \u043a \u043a\u043e\u0442\u043e\u0440\u043e\u043c\u0443 \u043c\u043e\u0436\u043d\u043e \u043f\u0440\u0438\u043a\u0440\u0435\u043f\u0438\u0442\u044c \u0433\u0435\u043e\u043c\u0435\u0442\u0440\u0438\u044e, \u043e\u0441\u0432\u0435\u0449\u0435\u043d\u0438\u0435, \u043a\u0430\u043c\u0435\u0440\u044b \u0438\u043b\u0438 \u0434\u0440\u0443\u0433\u043e\u0439 \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0430\u0435\u043c\u044b\u0439 \u043a\u043e\u043d\u0442\u0435\u043d\u0442.<\/p>\n<pre><code class=\"swift\">private let cameraNode = SCNNode() cameraNode.camera = SCNCamera() scene.rootNode.addChildNode(cameraNode)<\/code><\/pre>\n<p><a href=\"https:\/\/developer.apple.com\/documentation\/scenekit\/scncamera\">SCNCamera<\/a> \u2014 \u043d\u0430\u0431\u043e\u0440 \u0430\u0442\u0440\u0438\u0431\u0443\u0442\u043e\u0432 \u043a\u0430\u043c\u0435\u0440\u044b, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043c\u043e\u0436\u043d\u043e \u043f\u0440\u0438\u043a\u0440\u0435\u043f\u0438\u0442\u044c \u043a <code>SCNNode<\/code>, \u0447\u0442\u043e\u0431\u044b \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0438\u0442\u044c \u0442\u043e\u0447\u043a\u0443, \u0441 \u043a\u043e\u0442\u043e\u0440\u043e\u0439 \u043c\u044b \u0431\u0443\u0434\u0435\u043c \u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c \u043d\u0430 \u043a\u043e\u043d\u0442\u0435\u043d\u0442. \u0412 \u0434\u0430\u043b\u044c\u043d\u0435\u0439\u0448\u0435\u043c \u043c\u044b \u043f\u0440\u0438\u0441\u0432\u0430\u0438\u0432\u0430\u0435\u043c\u00a0\u0432 \u043d\u0435\u0451 \u043f\u043e\u0437\u0438\u0446\u0438\u044e, \u0447\u0442\u043e \u0440\u0430\u0441\u0441\u0447\u0438\u0442\u044b\u0432\u0430\u0435\u043c \u0438\u0441\u0445\u043e\u0434\u044f \u0438\u0437 \u0432\u044c\u044e \u043c\u043e\u0434\u0435\u043b\u0435\u0439 \u0438 \u0438\u0445 \u043c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u044c\u043d\u043e\u0439 \u0433\u043b\u0443\u0431\u0438\u043d\u044b.<\/p>\n<p>\u041f\u0435\u0440\u0435\u0439\u0434\u0435\u043c \u043a ViewModel \u0438 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0438\u043c\u0441\u044f \u0441 \u0442\u0435\u043c, \u0447\u0442\u043e \u043d\u0430\u043c \u0432 \u043d\u0435\u0439 \u043d\u0443\u0436\u043d\u043e. \u041f\u043e\u0434 \u0432\u044c\u044e-\u043c\u043e\u0434\u0435\u043b\u044c\u044e \u044f \u043f\u043e\u0434\u0440\u0430\u0437\u0443\u043c\u0435\u0432\u0430\u044e \u0434\u0430\u043d\u043d\u044b\u0435 \u0434\u043b\u044f \u043f\u043e\u043a\u0430\u0437\u0430 \u0432\u044c\u044e, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043d\u0435 \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0442 \u043a\u0430\u043a\u043e\u0439-\u043b\u0438\u0431\u043e \u0431\u0438\u0437\u043d\u0435\u0441-\u043b\u043e\u0433\u0438\u043a\u0438. \u041d\u0430\u043c \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c \u043c\u0430\u0441\u0441\u0438\u0432 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u043e\u0432, \u0434\u043b\u044f \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u0438\u0437 \u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u0431\u0443\u0434\u0435\u043c \u0441\u043e\u0437\u0434\u0430\u0432\u0430\u0442\u044c \u043d\u043e\u0434\u0443, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0431\u0443\u0434\u0435\u0442 \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0442\u044c\u0441\u044f \u0432 \u0441\u0446\u0435\u043d\u0443. \u0418 \u0434\u043b\u044f \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u0442\u0430\u043a\u043e\u0433\u043e \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u0430 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u044b:<\/p>\n<ul>\n<li>\n<p>\u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0435 \u0432\u044c\u044e \u2014 \u0441\u043d\u0430\u043f\u0448\u043e\u0442;<\/p>\n<\/li>\n<li>\n<p>\u0433\u043b\u0443\u0431\u0438\u043d\u0430 \u2014 \u043f\u043e\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u0432\u044c\u044e \u043f\u043e z-\u043e\u0441\u0438;<\/p>\n<\/li>\n<li>\n<p>\u0440\u0430\u0437\u043c\u0435\u0440 \u0438 \u043f\u043e\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u2014 \u0434\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c \u0444\u0440\u0435\u0439\u043c;<\/p>\n<\/li>\n<li>\n<p>\u0441\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u0438\u0441\u0445\u043e\u0434\u043d\u0443\u044e \u0432\u044c\u044e \u0434\u043b\u044f \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0445 \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0439 (\u043e\u0442\u043a\u0440\u044b\u0442\u0438\u0435 \u0434\u0435\u0442\u0430\u043b\u0435\u0439).<\/p>\n<\/li>\n<\/ul>\n<p>\u0418\u0442\u043e\u0433\u043e, \u0432\u044c\u044e-\u043c\u043e\u0434\u0435\u043b\u044c \u0431\u0443\u0434\u0435\u0442 \u0432\u044b\u0433\u043b\u044f\u0434\u0435\u0442\u044c \u0442\u0430\u043a:\u00a0<\/p>\n<pre><code class=\"swift\">enum VisualDebugger {     enum PresentModuleData {         struct ViewModel: Equatable {             let layoutModels: [LayoutModel]         }     }      struct LayoutModel: Equatable {         let image: UIImage         let depth: Float         let frame: CGRect         let view: UIView     } }<\/code><\/pre>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c, \u043f\u0440\u0438 \u043f\u0440\u0438\u0441\u0432\u0430\u0438\u0432\u0430\u043d\u0438\u0438 \u0432\u044c\u044e-\u043c\u043e\u0434\u0435\u043b\u0438 \u0432\u043e \u0432\u044c\u044e \u043d\u0430\u0448\u0435\u0433\u043e VisualDebugger-\u0430, \u0434\u043b\u044f \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u043e\u0431\u044a\u0435\u043a\u0442\u0430 \u0438\u0437 \u043c\u0430\u0441\u0441\u0438\u0432\u0430 \u043c\u044b \u0431\u0443\u0434\u0435\u043c \u0441\u043e\u0437\u0434\u0430\u0432\u0430\u0442\u044c \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u0443\u044e \u043d\u043e\u0434\u0443, \u043a\u043e\u0442\u043e\u0440\u0443\u044e \u0431\u0443\u0434\u0435\u043c \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0442\u044c \u043a\u0430\u043a childNode \u0432 \u0441\u0446\u0435\u043d\u0443.<\/p>\n<p>\u0414\u0435\u043b\u0430\u0442\u044c \u043c\u044b \u0431\u0443\u0434\u0435\u043c \u044d\u0442\u043e c \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0439 \u0444\u0443\u043d\u043a\u0446\u0438\u0438:<\/p>\n<pre><code class=\"swift\">func addChildNode(for model: VisualDebugger.LayoutModel) {     let geometry = SCNPlane(         width: model.frame.size.width \/ \u0441oefficient,         height: model.frame.size.height \/ \u0441oefficient     )     let material = SCNMaterial()     material.isDoubleSided = true     material.diffuse.contents = model.image     geometry.materials = [material]     let geometryNode = SCNNode(geometry: geometry)     geometryNode.position = calculatePosition(        for: model,        spacing: appearance.defaultZSpacing     )     geometryNode.accessibilityLabel = makeID(for: model.view)     childNodes.append(geometryNode)     scene.rootNode.addChildNode(geometryNode) }<\/code><\/pre>\n<p>\u041f\u0435\u0440\u0432\u044b\u043c \u0434\u0435\u043b\u043e\u043c \u0441\u043e\u0437\u0434\u0430\u0435\u043c \u0433\u0435\u043e\u043c\u0435\u0442\u0440\u0438\u044e \u2014 \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u0435 3D-\u0444\u0438\u0433\u0443\u0440\u044b \u043d\u043e\u0434\u0430. \u041c\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c <a href=\"https:\/\/developer.apple.com\/documentation\/scenekit\/scnplane\">SCNPlane<\/a> \u2014 \u044d\u0442\u043e \u043f\u0440\u044f\u043c\u043e\u0443\u0433\u043e\u043b\u044c\u043d\u0438\u043a, \u043a\u043e\u0442\u043e\u0440\u043e\u043c\u0443 \u043c\u044b \u0437\u0430\u0434\u0430\u0435\u043c \u0448\u0438\u0440\u0438\u043d\u0443 \u0438 \u0432\u044b\u0441\u043e\u0442\u0443. \u0422\u0430\u043a\u0436\u0435 SceneKit \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u0441\u043e\u0437\u0434\u0430\u0432\u0430\u0442\u044c \u043f\u0440\u043e\u0441\u0442\u044b\u0435 \u043e\u0431\u044a\u0435\u043c\u043d\u044b\u0435 \u0444\u0438\u0433\u0443\u0440\u044b \u0442\u0438\u043f\u0430 \u0448\u0430\u0440\u0430, \u043a\u0443\u0431\u0430, \u0446\u0438\u043b\u0438\u043d\u0434\u0440\u0430 \u0438 \u0438\u043c\u043f\u043e\u0440\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0441\u043b\u043e\u0436\u043d\u044b\u0435 3D-\u043c\u043e\u0434\u0435\u043b\u0438 \u0438\u0437 \u0432\u043d\u0435\u0448\u043d\u0438\u0445 \u0440\u0435\u0434\u0430\u043a\u0442\u043e\u0440\u043e\u0432.<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/ea2\/e81\/db2\/ea2e81db27c99bb45c5d685c38a1d613.png\" width=\"1914\" height=\"1602\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/ea2\/e81\/db2\/ea2e81db27c99bb45c5d685c38a1d613.png\"\/><\/figure>\n<p>\u041e\u0431\u044a\u0435\u043a\u0442 \u0435\u0441\u0442\u044c. \u0410 \u0438\u0437 \u043a\u0430\u043a\u043e\u0433\u043e \u043e\u043d \u043c\u0430\u0442\u0435\u0440\u0438\u0430\u043b\u0430? \u0414\u043b\u044f \u043f\u0440\u0438\u0441\u0432\u043e\u0435\u043d\u0438\u044f \u043c\u0430\u0442\u0435\u0440\u0438\u0430\u043b\u0430 \u0434\u043b\u044f \u043d\u0430\u0448\u0435\u0439 \u0433\u0435\u043e\u043c\u0435\u0442\u0440\u0438\u0438 \u0431\u0435\u0440\u0451\u043c <a href=\"https:\/\/developer.apple.com\/documentation\/scenekit\/scnmaterial\">SCNMaterial<\/a> \u2014 \u043d\u0430\u0431\u043e\u0440 \u0441\u0432\u043e\u0439\u0441\u0442\u0432, \u043e\u043f\u0438\u0441\u044b\u0432\u0430\u044e\u0449\u0438\u0445 \u0442\u043e, \u043a\u0430\u043a \u0431\u0443\u0434\u0435\u0442 \u0432\u044b\u0433\u043b\u044f\u0434\u0435\u0442\u044c \u043d\u0430\u0448\u0430 \u0433\u0435\u043e\u043c\u0435\u0442\u0440\u0438\u044f \u043f\u043e\u0441\u043b\u0435 \u0440\u0435\u043d\u0434\u0435\u0440\u0438\u043d\u0433\u0430.<\/p>\n<p>Difuse \u2014 \u044d\u0442\u043e \u043e\u0431\u044a\u0435\u043a\u0442, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0435\u0442 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0441\u0432\u0435\u0442\u0430, \u0434\u0438\u0444\u0444\u0443\u0437\u043d\u043e \u043e\u0442\u0440\u0430\u0436\u0435\u043d\u043d\u043e\u0433\u043e \u043e\u0442 \u043f\u043e\u0432\u0435\u0440\u0445\u043d\u043e\u0441\u0442\u0438. \u0412 \u043d\u0435\u0433\u043e \u043c\u044b \u043f\u0440\u0438\u0441\u0432\u0430\u0438\u0432\u0430\u0435\u043c \u043a\u043e\u043d\u0442\u0435\u043d\u0442 \u2014 \u044d\u0442\u043e \u043d\u0430\u0448\u0435 \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0435.<\/p>\n<p>\u0422\u0430\u043a\u0436\u0435 SceneKit \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u043d\u0430\u0441\u0442\u0440\u043e\u0438\u0442\u044c metalness \u0438 roughness \u2014 \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u0430, \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u044e\u0449\u0438\u0435 \u0442\u043e, \u043d\u0430\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u043c\u0430\u0442\u0435\u0440\u0438\u0430\u043b \u0431\u0443\u0434\u0435\u0442 \u043f\u043e\u0445\u043e\u0436 \u043d\u0430 \u043c\u0435\u0442\u0430\u043b\u043b \u0438 \u0442\u043e, \u043d\u0430\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0443 \u043d\u0435\u0433\u043e \u0431\u0443\u0434\u0435\u0442 \u043d\u0430\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0440\u043e\u0432\u043d\u0430\u044f \u043f\u043e\u0432\u0435\u0440\u0445\u043d\u043e\u0441\u0442\u044c, \u043d\u043e \u0432 \u0440\u0430\u043c\u043a\u0430\u0445 \u043d\u0430\u0448\u0435\u0439 \u0444\u0438\u0447\u0438 \u043c\u044b \u043d\u0435 \u0431\u0443\u0434\u0435\u043c \u044d\u0442\u043e\u0433\u043e \u0434\u0435\u043b\u0430\u0442\u044c \u2014 \u043d\u0435 \u043e\u0441\u043e\u0431\u043e \u0438 \u043d\u0443\u0436\u043d\u043e \ud83d\ude42<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/264\/6d3\/0b5\/2646d30b5a0797492f8f157ab492e2c7.png\" width=\"1600\" height=\"850\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/264\/6d3\/0b5\/2646d30b5a0797492f8f157ab492e2c7.png\"\/><\/figure>\n<p>\u0414\u0430\u043b\u0435\u0435 \u0441\u043e\u0437\u0434\u0430\u0434\u0438\u043c \u043d\u043e\u0434\u0443 \u043d\u0430 \u0431\u0430\u0437\u0435 \u0433\u0435\u043e\u043c\u0435\u0442\u0440\u0438\u0438 \u0438 \u0440\u0430\u0441\u0441\u0447\u0438\u0442\u0430\u0435\u043c \u0434\u043b\u044f \u043d\u0435\u0451 \u043f\u043e\u0437\u0438\u0446\u0438\u044e \u043d\u0430 \u0431\u0430\u0437\u0435 \u0444\u0440\u0435\u0439\u043c\u0430 \u0432\u044c\u044e\u0448\u043a\u0438. \u041f\u0440\u0438 \u0440\u0430\u0441\u0447\u0435\u0442\u0435 \u043f\u043e\u0437\u0438\u0446\u0438\u0438 \u043d\u043e\u0434\u044b \u0441\u0442\u043e\u0438\u0442 \u0443\u0447\u0438\u0442\u044b\u0432\u0430\u0442\u044c, \u0447\u0442\u043e \u043e\u0441\u044c \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442 \u0432 SceneKit \u043e\u0442\u043b\u0438\u0447\u0430\u0435\u0442\u0441\u044f \u043e\u0442 \u0442\u043e\u0439, \u043a\u043e\u0442\u043e\u0440\u0443\u044e \u043c\u044b \u043f\u0440\u0438\u0432\u044b\u043a\u043b\u0438 \u0432\u0438\u0434\u0435\u0442\u044c \u0432 UIKit \u2014 \u043e\u0441\u044c Y \u0438\u043d\u0432\u0435\u0440\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0430, \u0430 \u043f\u043e\u0437\u0438\u0446\u0438\u044f \u043d\u0430\u0448\u0435\u0439 \u0433\u0435\u043e\u043c\u0435\u0442\u0440\u0438\u0438 \u0441\u0447\u0438\u0442\u0430\u0435\u0442\u0441\u044f \u043e\u0442 \u0435\u0451 \u0441\u0435\u0440\u0435\u0434\u0438\u043d\u044b. <\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/2a5\/286\/dbc\/2a5286dbc6d35cd999fa9c052a14ef68.png\" width=\"2610\" height=\"1606\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/2a5\/286\/dbc\/2a5286dbc6d35cd999fa9c052a14ef68.png\"\/><\/figure>\n<p>\u0418 \u043f\u0435\u0440\u0435\u0433\u043e\u043d\u044f\u0442\u044c \u0444\u0440\u0435\u0439\u043c \u0432 \u043f\u043e\u0437\u0438\u0446\u0438\u044e \u043d\u043e\u0434\u044b (<a href=\"https:\/\/developer.apple.com\/documentation\/scenekit\/scnvector3\">SCNVector3<\/a>) \u043c\u044b \u0431\u0443\u0434\u0435\u043c \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0439 \u0444\u0443\u043d\u043a\u0446\u0438\u0438:<\/p>\n<pre><code class=\"swift\">func calculatePosition(     for model: VisualDebugger.LayoutModel,      spacing: Float ) -> SCNVector3 {     SCNVector3(         x: Float(model.frame.midX \/ \u0441oefficient),         y: Float(model.frame.midY.negative \/ \u0441oefficient),         z: model.depth * spacing      ) }<\/code><\/pre>\n<p>\u0417\u0434\u0435\u0441\u044c \u0436\u0435 \u043f\u0440\u0438\u0441\u0432\u043e\u0438\u043c <code>accessabilityLabel<\/code> \u0434\u043b\u044f \u043d\u043e\u0434\u044b, \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u044b\u0439 \u0434\u043b\u044f \u043f\u043e\u0438\u0441\u043a\u0430 \u0430\u0441\u0441\u043e\u0446\u0438\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u043e\u0439 \u0432\u044c\u044e \u043c\u043e\u0434\u0435\u043b\u0438 \u043f\u0440\u0438 \u0442\u0430\u043f\u0435. \u0410 \u0442\u0430\u043f\u044b \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u044b\u0432\u0430\u0435\u043c \u043f\u0440\u043e\u0441\u0442\u044b\u043c \u043d\u0430\u0432\u0435\u0448\u0438\u0432\u0430\u043d\u0438\u0435\u043c  <code>gestureRecognizer<\/code> \u043d\u0430 <code>sceneView<\/code> \u0438 \u0432\u044b\u0437\u043e\u0432\u043e\u043c <code>hitTest<\/code> \u0434\u043b\u044f <code>sceneView<\/code>, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0431\u0443\u0434\u0435\u0442 \u0432\u044b\u0434\u0430\u0432\u0430\u0442\u044c \u043d\u0443\u0436\u043d\u0443\u044e \u043d\u043e\u0434\u0443.<\/p>\n<p>\u041f\u043b\u044e\u0441, \u0431\u044b\u043b\u0438 \u043d\u0430\u0441\u0442\u0440\u043e\u0435\u043d\u044b \u0441\u043b\u0430\u0439\u0434\u0435\u0440\u044b \u0440\u0430\u0441\u0441\u0442\u043e\u044f\u043d\u0438\u044f \u043c\u0435\u0436\u0434\u0443 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u0430\u043c\u0438 \u0438 \u0433\u043b\u0443\u0431\u0438\u043d\u044b \u043f\u0440\u043e\u0440\u0438\u0441\u043e\u0432\u043a\u0438. \u041e\u043d\u0438 \u0441\u043a\u0440\u044b\u0432\u0430\u044e\u0442 \u043d\u043e\u0434\u0443, \u0435\u0441\u043b\u0438 \u0433\u043b\u0443\u0431\u0438\u043d\u0430 \u0431\u043e\u043b\u044c\u0448\u0435 \u0443\u043a\u0430\u0437\u0430\u043d\u043d\u043e\u0439 \u0438\u043b\u0438 \u0438\u0437\u043c\u0435\u043d\u044f\u044e\u0442 \u043f\u043e\u0437\u0438\u0446\u0438\u044e \u043d\u043e\u0434, \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0435\u043d\u043d\u043e.<\/p>\n<p>\u041d\u0430\u043f\u0438\u0441\u0430\u0432 \u0441\u043e\u0432\u0441\u0435\u043c \u043d\u0435\u043c\u043d\u043e\u0433\u043e \u043a\u043e\u0434\u0430 \u0434\u043b\u044f \u0432\u044c\u044e \u0441\u043b\u043e\u044f \u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044f \u043f\u043e\u0434\u0433\u043e\u0442\u043e\u0432\u043a\u0443 \u0434\u0430\u043d\u043d\u044b\u0445 \u0434\u043b\u044f \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044f \u0438\u0437 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438 Glance, \u043f\u043e\u043b\u0443\u0447\u0438\u043b\u0441\u044f \u0443\u0436\u0435 \u0432\u043f\u043e\u043b\u043d\u0435 \u0440\u0430\u0431\u043e\u0447\u0438\u0439 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442. <\/p>\n<div class=\"tm-iframe_temp\" data-src=\"https:\/\/embedd.srv.habr.com\/iframe\/655cbcdb6f566b30a58e3471\" data-style=\"\" id=\"655cbcdb6f566b30a58e3471\" width=\"\"><\/div>\n<p>\u041a\u0430\u043a \u0432\u044b \u043c\u043e\u0433\u043b\u0438 \u0443\u0432\u0438\u0434\u0435\u0442\u044c, SceneKit \u0438\u043d\u0442\u0443\u0438\u0442\u0438\u0432\u043d\u043e \u043f\u043e\u043d\u044f\u0442\u0435\u043d, \u0434\u043e\u0432\u043e\u043b\u044c\u043d\u043e \u043f\u0440\u043e\u0441\u0442 \u0438 \u0431\u044b\u0441\u0442\u0440 \u0432 \u043e\u0441\u0432\u043e\u0435\u043d\u0438\u0438. \u0417\u0430 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0447\u0430\u0441\u043e\u0432 \u044f \u043f\u043e\u043b\u0443\u0447\u0438\u043b \u0433\u043e\u0442\u043e\u0432\u0443\u044e \u0432\u044c\u044e\u0448\u043a\u0443, \u0432\u0437\u0433\u043b\u044f\u043d\u0443\u0432 \u043d\u0430 \u043a\u043e\u0442\u043e\u0440\u0443\u044e, \u043c\u043e\u0436\u043d\u043e \u043f\u043e\u0447\u0443\u0432\u0441\u0442\u0432\u043e\u0432\u0430\u0442\u044c \u0432\u0430\u0443-\u044d\u0444\u0444\u0435\u043a\u0442, \u0445\u043e\u0442\u044c \u0438 \u0441\u0438\u043b \u0442\u0443\u0434\u0430 \u043e\u0441\u043e\u0431\u043e \u043d\u0435 \u0432\u043a\u043b\u0430\u0434\u044b\u0432\u0430\u043b\u043e\u0441\u044c.<\/p>\n<p>\u041f\u0435\u0440\u0435\u0439\u0434\u0435\u043c \u043a \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0439 \u0447\u0430\u0441\u0442\u0438 \u2014 \u043f\u043e\u0434\u0433\u043e\u0442\u043e\u0432\u0438\u043c \u0434\u0430\u043d\u043d\u044b\u0435 \u0434\u043b\u044f \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044f.<\/p>\n<h2>\u0413\u043e\u0442\u043e\u0432\u0438\u043c \u0434\u0430\u043d\u043d\u044b\u0435 \u0434\u043b\u044f \u043f\u043e\u043a\u0430\u0437\u0430<\/h2>\n<p><strong>\u0414\u0438\u0441\u043a\u043b\u0435\u0439\u043c\u0435\u0440!<\/strong> \u041d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0444\u0440\u0430\u0433\u043c\u0435\u043d\u0442\u044b \u043a\u043e\u0434\u0430 \u043c\u043e\u0433\u0443\u0442 \u0432\u0430\u0441 \u0448\u043e\u043a\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0438 \u043c\u043e\u0436\u0435\u0442 \u043f\u043e\u044f\u0432\u0438\u0442\u044c\u0441\u044f \u043d\u0435\u043f\u0440\u0435\u043e\u0434\u043e\u043b\u0438\u043c\u043e\u0435 \u0436\u0435\u043b\u0430\u043d\u0438\u0435 \u0447\u0442\u043e-\u0442\u043e \u043e\u0442\u0440\u0435\u0444\u0430\u043a\u0442\u043e\u0440\u0438\u0442\u044c \u0438\u043b\u0438 \u0441\u043a\u0430\u0437\u0430\u0442\u044c \u2014 \u043d\u0435 \u043f\u043e <a href=\"https:\/\/github.com\/alfa-laboratory\/YARCH\">\u044f\u0440\u043a\u0443<\/a>. \u041f\u0440\u043e\u0448\u0443 \u043e\u0442\u043d\u0435\u0441\u0442\u0438\u0441\u044c \u0441 \u043f\u043e\u043d\u0438\u043c\u0430\u043d\u0438\u0435\u043c \u0438 \u043f\u043e\u043c\u043d\u0438\u0442\u044c, \u0447\u0442\u043e \u043d\u0430 \u0437\u0430\u0434\u0430\u0447\u0443 \u0438\u0437\u043d\u0430\u0447\u0430\u043b\u044c\u043d\u043e \u043e\u0442\u0432\u043e\u0434\u0438\u043b\u043e\u0441\u044c \u0442\u043e\u043b\u044c\u043a\u043e 4 \u0434\u043d\u044f. <\/p>\n<p>\u041d\u0430\u0447\u043d\u0443 \u0441 \u0442\u043e\u0433\u043e, \u0447\u0442\u043e \u043e\u0441\u043d\u043e\u0432\u043d\u044b\u0435 \u0441\u043b\u043e\u0436\u043d\u043e\u0441\u0442\u0438 \u0441 \u0437\u0430\u0434\u0430\u0447\u0435\u0439 \u044f \u0432\u0441\u0442\u0440\u0435\u0442\u0438\u043b \u0438\u043c\u0435\u043d\u043d\u043e \u043d\u0430 \u044d\u0442\u043e\u043c \u044d\u0442\u0430\u043f\u0435. \u0411\u044b\u043b\u043e \u0434\u043e\u0432\u043e\u043b\u044c\u043d\u043e \u0441\u043b\u043e\u0436\u043d\u043e \u0441\u0440\u0430\u0437\u0443 \u0441\u0444\u043e\u0440\u043c\u0443\u043b\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0434\u043b\u044f \u0441\u0435\u0431\u044f \u0432\u0441\u0435 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u044b \u0442\u043e\u0433\u043e, \u0447\u0442\u043e \u0438\u043c\u0435\u043d\u043d\u043e \u0441\u0447\u0438\u0442\u0430\u0442\u044c \u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u044b\u043c \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0435\u043c. \u041d\u043e \u0432\u0441\u0451-\u0442\u0430\u043a\u0438 \u044f \u0432\u044b\u0432\u0435\u043b \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043a\u0440\u0438\u0442\u0435\u0440\u0438\u0438 \u0440\u0430\u0431\u043e\u0442\u044b, \u043e\u0442\u0442\u0430\u043b\u043a\u0438\u0432\u0430\u044f\u0441\u044c \u043e\u0442 \u0442\u043e\u0433\u043e, \u0447\u0442\u043e \u0431\u044b\u043b\u043e \u043d\u0435 \u0442\u0430\u043a \u0432 \u0433\u043e\u0442\u043e\u0432\u044b\u0445 \u0440\u0435\u0448\u0435\u043d\u0438\u044f\u0445:<\/p>\n<ul>\n<li>\n<p>\u0422\u0435 \u0432\u044c\u044e, \u0447\u0442\u043e \u043c\u044b \u043d\u0435 \u0432\u0438\u0434\u0438\u043c, \u043d\u0435 \u0434\u043e\u043b\u0436\u043d\u044b \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0430\u0442\u044c\u0441\u044f \u0438 \u043d\u0430\u043e\u0431\u043e\u0440\u043e\u0442. \u042d\u0442\u043e \u0437\u043d\u0430\u0447\u0438\u0442, \u0447\u0442\u043e \u0432\u044c\u044e \u043d\u0435 \u0434\u043e\u043b\u0436\u043d\u0430 \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0430\u0435\u0442\u0441\u044f \u0435\u0441\u043b\u0438 <code>isHidden == true<\/code>, <code>alpha == 0<\/code> \u0438 \u0432\u044c\u044e \u043d\u0435 \u0432\u043b\u0435\u0437\u0430\u0435\u0442 \u0432 \u043e\u0431\u043b\u0430\u0441\u0442\u044c \u0432\u0438\u0434\u0438\u043c\u043e\u0441\u0442\u0438 \u0440\u0443\u0442\u043e\u0432\u043e\u0439 \u0432\u044c\u044e (\u044d\u0442\u043e \u0442\u0430 \u0432\u044c\u044e, \u0434\u043b\u044f \u043a\u043e\u0442\u043e\u0440\u043e\u0439 \u043c\u044b \u0441\u0442\u0440\u043e\u0438\u043c \u0433\u0440\u0430\u0444). <\/p>\n<\/li>\n<li>\n<p>\u0415\u0441\u043b\u0438 \u0441\u0430\u043c\u0430 \u0432\u044c\u044e \u043d\u0435 \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0430\u0435\u0442\u0441\u044f, \u043d\u043e \u0443 \u043d\u0435\u0435 \u0435\u0441\u0442\u044c \u0441\u0430\u0431\u0432\u044c\u044e, \u0432\u044b\u0445\u043e\u0434\u044f\u0449\u0430\u044f \u0437\u0430 \u0435\u0435 \u0431\u0430\u0443\u043d\u0434\u0441, \u0438 \u043f\u0440\u0438 \u044d\u0442\u043e\u043c \u0443 \u043d\u0435\u0451<code>clipsToBounds == false<\/code>, \u0442\u043e \u0441\u0430\u0431\u0432\u044c\u044e \u043c\u044b \u0443\u0436\u0435 \u0434\u043e\u043b\u0436\u043d\u044b \u043e\u0442\u0440\u0438\u0441\u043e\u0432\u0430\u0442\u044c.<\/p>\n<\/li>\n<li>\n<p>\u0422\u0435 \u0447\u0430\u0441\u0442\u0438 \u0432\u044c\u044e, \u0447\u0442\u043e \u043c\u044b \u043d\u0435 \u0432\u0438\u0434\u0438\u043c, \u0434\u043e\u043b\u0436\u043d\u044b \u043e\u0431\u0440\u0435\u0437\u0430\u0442\u044c\u0441\u044f.<\/p>\n<\/li>\n<li>\n<p>\u0414\u043e\u043b\u0436\u043d\u0430 \u0432\u044b\u0441\u0442\u0430\u0432\u043b\u044f\u0442\u044c\u0441\u044f \u043a\u043e\u0440\u0440\u0435\u043a\u0442\u043d\u0430\u044f \u00ab\u0433\u043b\u0443\u0431\u0438\u043d\u0430\u00bb. \u0423\u0447\u0438\u0442\u044b\u0432\u0430\u0435\u043c, \u0447\u0442\u043e \u0434\u043b\u044f \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u0438\u0445 \u0432\u044c\u044e \u043e\u0434\u043d\u043e\u0433\u043e \u0440\u043e\u0434\u0438\u0442\u0435\u043b\u044f, \u0435\u0441\u043b\u0438 \u0438\u0445 \u0444\u0440\u0435\u0439\u043c\u044b \u043d\u0435 \u043f\u0435\u0440\u0435\u0441\u0435\u043a\u0430\u044e\u0442\u0441\u044f, \u0433\u043b\u0443\u0431\u0438\u043d\u0430 \u0434\u043e\u043b\u0436\u043d\u0430 \u0431\u044b\u0442\u044c \u043e\u0434\u0438\u043d\u0430\u043a\u043e\u0432\u0430.<\/p>\n<\/li>\n<\/ul>\n<h3>\u041f\u0440\u043e\u0432\u0430\u0439\u0434\u0435\u0440 \u0434\u0430\u043d\u043d\u044b\u0445<\/h3>\n<p>\u0417\u0434\u0435\u0441\u044c \u0432\u0441\u0451 \u0437\u0430\u0432\u044f\u0437\u0430\u043d\u043e \u043d\u0430 \u0444\u0443\u043d\u043a\u0446\u0438\u044e, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0440\u0435\u043a\u0443\u0440\u0441\u0438\u0432\u043d\u043e \u043f\u0440\u043e\u0445\u043e\u0434\u0438\u0442 \u043f\u043e \u0432\u0441\u0435\u043c \u0441\u0430\u0431\u0432\u044c\u044e, \u0440\u0430\u0441\u0441\u0447\u0438\u0442\u044b\u0432\u0430\u0435\u0442 \u0438\u0445 \u0433\u043b\u0443\u0431\u0438\u043d\u0443 \u0438 \u043e\u0442\u0434\u0430\u0435\u0442 \u0440\u0430\u0431\u043e\u0442\u0443 \u043d\u0430 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u043c\u043e\u0434\u0435\u043b\u0438 \u0431\u0438\u043b\u0434\u0435\u0440\u0443.<\/p>\n<pre><code class=\"swift\">func getViewHierarchy() ->[VisualDebugger.LayoutModel] {     var depth: Float = 0     return getLayoutModelsRecursively(for: rootView, rootView: rootView, depth: &amp;depth) }  func getLayoutModelsRecursively(     for view: UIView,     rootView: UIView,     depth: inout Float ) -> [VisualDebugger.LayoutModel] {     guard checkValidity(of: view) else { return [] }     var result: [VisualDebugger.LayoutModel] = []     layoutModelBuilder.buildLayoutModel(for: view, in: rootView, depth: depth).flatMap {         result.append($0)     }     ... }  func checkValidity(of view: UIView) -> Bool {     !filteredViewsTags.contains(view.tag) &amp;&amp; !view.isHidden &amp;&amp; view.alpha >= 0.01 }<\/code><\/pre>\n<ul>\n<li>\n<p>\u0421\u043d\u0430\u0447\u0430\u043b\u0430 \u043c\u044b \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u043c, \u043d\u0443\u0436\u043d\u043e \u043b\u0438 \u043d\u0430\u043c \u043e\u0442\u043e\u0431\u0440\u0430\u0437\u0438\u0442\u044c \u044d\u0442\u0443 \u0432\u044c\u044e \u2014 \u044d\u0442\u043e \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e, \u043f\u043e\u0441\u043a\u043e\u043b\u044c\u043a\u0443 \u043d\u0443\u0436\u043d\u043e \u043e\u0442\u0444\u0438\u043b\u044c\u0442\u0440\u043e\u0432\u044b\u0432\u0430\u0442\u044c \u0432\u044c\u044e, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043d\u0443\u0436\u043d\u043e \u0434\u0435\u0431\u0430\u0436\u0438\u0442\u044c, \u043e\u0442 \u0432\u044c\u044e\u0448\u0435\u043a \u0437\u0430\u043f\u0440\u0435\u0437\u0435\u043d\u0447\u0435\u043d\u043d\u043e\u0433\u043e DebugMenu. <\/p>\n<\/li>\n<li>\n<p>\u041f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u043c, \u043d\u0435 \u0441\u043a\u0440\u044b\u0442\u0430 \u043b\u0438 \u0432\u044c\u044e \u0438 \u043d\u0435 \u0440\u0430\u0432\u043d\u0430 \u043b\u0438 \u043d\u0443\u043b\u044e \u0430\u043b\u044c\u0444\u0430.<\/p>\n<\/li>\n<\/ul>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u0434\u0430\u0432\u0430\u0439\u0442\u0435 \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0438\u043c, \u043a\u0430\u043a \u043c\u044b \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0435\u043c \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440 \u0433\u043b\u0443\u0431\u0438\u043d\u044b <code>depth<\/code>. <\/p>\n<ul>\n<li>\n<p>\u041f\u0435\u0440\u0435\u0434 \u043f\u0440\u043e\u0445\u043e\u0436\u0434\u0435\u043d\u0438\u0435\u043c \u0446\u0438\u043a\u043b\u0430 \u0441 \u0440\u0435\u043a\u0443\u0440\u0441\u0438\u0432\u043d\u044b\u043c \u0432\u044b\u0437\u043e\u0432\u043e\u043c \u0444\u0443\u043d\u043a\u0446\u0438\u0438, \u0441\u043e\u0437\u0434\u0430\u0451\u043c \u043c\u0430\u0441\u0441\u0438\u0432 \u0444\u0440\u0435\u0439\u043c\u043e\u0432, \u043a\u0443\u0434\u0430 \u0431\u0443\u0434\u0435\u043c \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0442\u044c \u0444\u0440\u0435\u0439\u043c\u044b \u0441\u0430\u0431\u0432\u044c\u044e\u0448\u0435\u043a, \u043f\u0440\u043e\u0431\u0435\u0433\u0430\u044f\u0441\u044c \u043f\u043e \u0446\u0438\u043a\u043b\u0443.<\/p>\n<\/li>\n<li>\n<p>\u041f\u0440\u0438 \u044d\u0442\u043e\u043c \u0441\u043c\u043e\u0442\u0440\u0438\u043c, \u043f\u0435\u0440\u0435\u0441\u0435\u043a\u0430\u0435\u0442\u0441\u044f \u043b\u0438 \u0444\u0440\u0435\u0439\u043c \u0442\u0435\u043a\u0443\u0449\u0435\u0439 \u0441\u0430\u0431\u0432\u044c\u044e \u0441 \u0442\u0435\u043c\u0438, \u0447\u0442\u043e \u0443\u0436\u0435 \u0435\u0441\u0442\u044c \u0432 \u043c\u0430\u0441\u0441\u0438\u0432\u0435, \u0438\u0437 \u0447\u0435\u0433\u043e \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0435\u043c, \u043a\u0430\u043a\u0443\u044e \u0433\u043b\u0443\u0431\u0438\u043d\u0443 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0434\u043b\u044f \u0442\u0435\u043a\u0443\u0449\u0435\u0433\u043e child-a  \u2014 \u0442\u0435\u043a\u0443\u0449\u0443\u044e \u0434\u043b\u044f \u0432\u044c\u044e + 1, \u043b\u0438\u0431\u043e \u043c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u044c\u043d\u0443\u044e + 1.<\/p>\n<\/li>\n<li>\n<p>\u0414\u0430\u043b\u0435\u0435, \u0440\u0435\u043a\u0443\u0440\u0441\u0438\u0432\u043d\u043e \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u043c \u043d\u0430\u0448\u0443 \u0444\u0443\u043d\u043a\u0446\u0438\u044e, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0438\u0437\u043c\u0435\u043d\u044f\u0435\u0442 childDepth, \u043f\u043e\u0441\u043b\u0435 \u0447\u0435\u0433\u043e \u0435\u0449\u0435 \u0438 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0435\u0442, \u043a\u0430\u043a\u043e\u0439 \u0438\u0437 depth \u0442\u0435\u043f\u0435\u0440\u044c \u043c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u044c\u043d\u044b\u0439.<\/p>\n<\/li>\n<\/ul>\n<figure class=\"float full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/3d0\/8e2\/156\/3d08e21564ca0502acb279df508df034.png\" width=\"1534\" height=\"810\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/3d0\/8e2\/156\/3d08e21564ca0502acb279df508df034.png\"\/><\/figure>\n<p>\u0421\u043c\u0435\u0448\u0430\u043b\u0438\u0441\u044c \u0440\u0435\u043a\u0443\u0440\u0441\u0438\u044f \u0438 inout \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u044b \u2014 \u043b\u0443\u0447\u0448\u0438\u0435 \u043f\u0440\u0430\u043a\u0442\u0438\u043a\u0438 \u00ab\u043f\u043e\u043d\u044f\u0442\u043d\u043e\u0433\u043e\u00bb \u043a\u043e\u0434\u0430. \u0412 \u043e\u0431\u0449\u0435\u043c, \u043a\u043e\u0434 \u0434\u043e\u0432\u043e\u043b\u044c\u043d\u043e \u0441\u043b\u043e\u0436\u0435\u043d \u0432 \u043f\u043e\u043d\u0438\u043c\u0430\u043d\u0438\u0438\u2026<\/p>\n<pre><code class=\"swift\">func getLayoutModelsRecursively(     for view: UIView,     rootView: UIView,     depth: inout Float ) -> [VisualDebugger.LayoutModel] {     guard checkValidity(of: view) else { return [] }     var result: [VisualDebugger.LayoutModel] = []     layoutModelBuilder.buildLayoutModel(for: view, in: rootView, depth: depth).flatMap {         result.append($0)     }     var subviewsFrames: [CGRect] = []     var maxChildDepth = depth     view.subviews.forEach { subview in         var childDepth = subviewsFrames.contains(where: { $0.intersects(subview.frame) })             ? maxChildDepth + Configuration.depthSpacing             : depth + Configuration.depthSpacing         let subviewLayoutModels = getLayoutModelsRecursively(             for: subview,             rootView: rootView,             depth: &amp;childDepth         )         subviewsFrames.append(subview.frame)         maxChildDepth = max(maxChildDepth, childDepth)         result.append(contentsOf: subviewLayoutModels)     }     depth = maxChildDepth     return result }<\/code><\/pre>\n<p>\u041d\u043e, \u043a\u0430\u0436\u0435\u0442\u0441\u044f, \u0442\u0435\u043f\u0435\u0440\u044c \u0443 \u043d\u0430\u0441 \u0435\u0441\u0442\u044c \u0432\u0441\u0451, \u0447\u0442\u043e\u0431\u044b \u0441\u043f\u043e\u043a\u043e\u0439\u043d\u043e \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u043c\u043e\u0434\u0435\u043b\u044c\u043a\u0443.<\/p>\n<p>\u041e\u0441\u0442\u0430\u0435\u0442\u0441\u044f \u043b\u0438\u0448\u044c \u043f\u043e\u0434\u0441\u0447\u0438\u0442\u0430\u0442\u044c \u0444\u0440\u0435\u0439\u043c \u0438 \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u0441\u043d\u0430\u043f\u0448\u043e\u0442, \u0447\u0442\u043e \u0438 \u0434\u0435\u043b\u0430\u0435\u0442\u0441\u044f \u0432 \u043e\u0441\u043d\u043e\u0432\u043d\u043e\u0439 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u0431\u0438\u043b\u0434\u0435\u0440\u0430, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0441\u043e\u0437\u0434\u0430\u0451\u0442 \u044d\u0442\u0443 \u043c\u043e\u0434\u0435\u043b\u044c.<\/p>\n<pre><code class=\"swift\">func buildLayoutModel(     for view: UIView,     in rootView: UIView,     depth: Float ) -> VisualDebugger.LayoutModel? {     guard let visibleFrameInRootView = visibleFrame(for: view, in: rootView) else {         return nil     }     let snapshot = makeSnapshot(         of: view,         in: rootView,         frameInRootView: view.superview?.convert(view.frame, to: rootView),         visibleFrameInRootView: visibleFrameInRootView     )     return snapshot.flatMap {         VisualDebugger.LayoutModel(             image: $0,             depth: depth,             frame: visibleFrameInRootView,             view: view         )     } }<\/code><\/pre>\n<p>\u041d\u043e \u0442\u0435\u043f\u0435\u0440\u044c \u0432\u043e\u0437\u043d\u0438\u043a\u0430\u0435\u0442 \u043e\u0447\u0435\u0440\u0435\u0434\u043d\u0430\u044f \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u0430.<\/p>\n<ul>\n<li>\n<p>\u041d\u0430\u043c \u043d\u0443\u0436\u043d\u043e \u043f\u0435\u0440\u0435\u0433\u043d\u0430\u0442\u044c \u0444\u0440\u0435\u0439\u043c \u0432\u044c\u044e \u0432 \u0441\u0438\u0441\u0442\u0435\u043c\u0443 \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442 \u043a\u043e\u0440\u043d\u0435\u0432\u043e\u0439 \u0432\u044c\u044e. <\/p>\n<\/li>\n<li>\n<p>\u041d\u0430\u043c \u043d\u0443\u0436\u043d\u043e \u0443\u0447\u0435\u0441\u0442\u044c, \u0447\u0442\u043e \u0432\u044c\u044e \u043f\u0440\u0438 \u044d\u0442\u043e\u043c \u043c\u043e\u0436\u0435\u0442 \u043d\u0435 \u0431\u044b\u0442\u044c \u0432\u0438\u0434\u043d\u0430 \u0438\u043b\u0438 \u0432\u0438\u0434\u043d\u0430 \u0431\u0443\u0434\u0435\u0442 \u0442\u043e\u043b\u044c\u043a\u043e \u043e\u0434\u043d\u0430 \u0435\u0451 \u0447\u0430\u0441\u0442\u044c.<\/p>\n<\/li>\n<\/ul>\n<p>\u0418 \u0432 \u044d\u0442\u043e\u043c \u043d\u0430\u043c \u0432\u043d\u043e\u0432\u044c \u043f\u043e\u043c\u043e\u0433\u0430\u0435\u0442 \u0440\u0435\u043a\u0443\u0440\u0441\u0438\u044f.<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/b52\/c3f\/383\/b52c3f38337684d281ccf3c0e664d740.png\" width=\"1332\" height=\"776\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/b52\/c3f\/383\/b52c3f38337684d281ccf3c0e664d740.png\"\/><\/figure>\n<p>\u0421 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u043d\u0438\u0436\u0435\u043b\u0435\u0436\u0430\u0449\u0435\u0439 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u043c\u044b \u0438\u0434\u0435\u043c \u043e\u0442 \u0440\u0430\u0441\u0441\u043c\u0430\u0442\u0440\u0438\u0432\u0430\u0435\u043c\u043e\u0439 \u0432\u044c\u044e \u0434\u043e \u043a\u043e\u0440\u043d\u0435\u0432\u043e\u0439, \u043a\u043e\u043d\u0432\u0435\u0440\u0442\u0438\u0440\u0443\u0435\u043c \u0444\u0440\u0435\u0439\u043c \u0432 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0443\u044e \u043f\u043e \u0438\u0435\u0440\u0430\u0440\u0445\u0438\u0438 \u0432\u044c\u044e, \u0443\u0447\u0438\u0442\u044b\u0432\u0430\u0435\u043c \u043f\u0435\u0440\u0435\u0441\u0435\u0447\u0435\u043d\u0438\u044f \u0441 \u0442\u0435\u043a\u0443\u0449\u0435\u0439 \u0438 \u0443\u0447\u0438\u0442\u044b\u0432\u0430\u0435\u043c <code>clipsToBounds<\/code> \u2014 \u0435\u0441\u043b\u0438 \u043e\u043d \u0432\u044b\u043a\u043b\u044e\u0447\u0435\u043d, \u0442\u043e \u043d\u0430\u043c, \u0432 \u0446\u0435\u043b\u043e\u043c, \u043d\u0435 \u0432\u0430\u0436\u043d\u043e, \u043f\u0435\u0440\u0435\u0441\u0435\u043a\u0430\u0435\u0442\u0441\u044f \u043b\u0438 \u0432\u044c\u044e \u0441 \u0442\u0435\u043a\u0443\u0449\u0435\u0439 \u0441\u0443\u043f\u0435\u0440\u0432\u044c\u044e \u0438\u043b\u0438 \u043d\u0435\u0442.<\/p>\n<pre><code class=\"swift\">\/\/\/ \u0412\u0438\u0434\u0438\u043c\u044b\u0439 \u0444\u0440\u0435\u0439\u043c \u0432\u044c\u044e \u0432 \u0440\u0443\u0442 \u0432\u044c\u044e func visibleFrame(for view: UIView, in rootView: UIView) -> CGRect? {     visibleFrame(         currentIntersection: view.bounds,         currentSuperview: view,         rootView: rootView     ) }  \/\/\/ - Parameters: \/\/\/   - currentIntersection: \u041f\u0435\u0440\u0435\u0441\u0435\u0447\u0435\u043d\u0438\u0435 \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u0443\u044e\u0449\u0435\u0439 \u043d\u0430\u0441 \u0432\u044c\u044e \u0441 currentSuperview \/\/\/   - currentSuperview: \u0422\u0435\u043a\u0443\u0449\u0430\u044f \u0441\u0443\u043f\u0435\u0440\u0432\u044c\u044e, \u043e\u0442\u043d\u043e\u0441\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u043a\u043e\u043d\u0442\u043e\u0440\u043e\u0439 \u0432 \u0442\u0435\u043a\u0443\u0449\u0435\u0439 \u0438\u0442\u0435\u0440\u0430\u0446\u0438\u0438 \u0440\u0430\u0441\u0441\u0447\u0438\u0442\u0430\u043d\u043e \u043f\u0440\u0435\u0441\u0435\u0447\u0435\u043d\u0438\u0435 \/\/\/   - rootView: \u0412\u044c\u044e, \u043e\u0442\u043d\u043e\u0441\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u043a\u043e\u0442\u043e\u0440\u043e\u0439 \u0440\u0430\u0441\u0441\u0447\u0438\u0442\u044b\u0432\u0430\u0435\u043c \u0444\u0440\u0435\u0439\u043c \/\/\/ - Returns: \u0412\u0438\u0434\u0438\u043c\u044b\u0439 \u0444\u0440\u0435\u0439\u043c \u0432 nextSuperview. \u041c\u043e\u0436\u0435\u0442 \u043d\u0435 \u044f\u0432\u043b\u044f\u0442\u044c\u0441\u044f \u043f\u0435\u0440\u0435ce\u0447\u0435\u043d\u0438\u0435\u043c, \u0435\u0441\u043b\u0438 nextView.clipsToBounds == false func visibleFrame(     currentIntersection: CGRect,     currentSuperview: UIView,     rootView: UIView ) -> CGRect? {     guard let nextSuperview = currentSuperview.superview, currentSuperview !== rootView else {         return currentIntersection     }      let frameInNextSuperview = nextSuperview.convert(currentIntersection, from: currentSuperview)     let intersectionWithNextSuperview = frameInNextSuperview.intersection(nextSuperview.bounds)     var nextIntersection: CGRect?      if !nextSuperview.clipsToBounds {         nextIntersection = frameInNextSuperview     } else if isIntersectionValid(intersectionWithNextSuperview) {         nextIntersection = intersectionWithNextSuperview     }      return nextIntersection.flatMap { nextIntersection in         return visibleFrame(             currentIntersection: nextIntersection,             currentSuperview: nextSuperview,             rootView: rootView         )     } }   func isIntersectionValid(_ frame: CGRect) -> Bool {     !frame.isNull &amp;&amp; frame.size.width > 0 &amp;&amp; frame.size.height > 0 }<\/code><\/pre>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u043d\u0430\u043c \u043d\u0443\u0436\u043d\u043e \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0441\u043d\u0430\u043f\u0448\u043e\u0442 \u0438 \u043e\u0431\u0440\u0435\u0437\u0430\u0442\u044c \u0435\u0433\u043e \u043f\u043e\u0434 \u0442\u0443 \u043e\u0431\u043b\u0430\u0441\u0442\u044c \u0432\u044c\u044e, \u043a\u043e\u0442\u043e\u0440\u0443\u044e \u0432\u0438\u0434\u0438\u043c. \u0415\u0441\u043b\u0438 \u0441 \u043e\u0431\u0440\u0435\u0437\u0430\u043d\u0438\u0435\u043c \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044f \u0432\u0441\u0435 \u043f\u043e\u043d\u044f\u0442\u043d\u043e, \u0442\u043e \u043a \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044e \u0441\u043d\u0430\u043f\u0448\u043e\u0442\u0430 \u0441\u0442\u043e\u0438\u0442 \u043f\u0440\u0438\u0433\u043b\u044f\u0434\u0435\u0442\u044c\u0441\u044f \u043f\u043e\u0431\u043b\u0438\u0436\u0435.<\/p>\n<pre><code class=\"swift\">func makeSnapshot(     of view: UIView,     in rootView: UIView,     frameInRootView: CGRect?,     visibleFrameInRootView: CGRect ) -> UIImage? {     var snapshot: UIImage? = makeSnapshot(of: view)     \/\/ \u0415\u0441\u043b\u0438 \u043a\u043e\u043d\u0442\u0435\u043d\u0442 \u043d\u0435 \u0432\u043b\u0435\u0437\u0430\u0435\u0442 \u0432 \u044d\u043a\u0440\u0430\u043d - \u043e\u0431\u0440\u0435\u0437\u0430\u0435\u043c \u0441\u043d\u0430\u043f\u0448\u043e\u0442 \u043f\u043e\u0434 \u0435\u0433\u043e \u0432\u0438\u0434\u0438\u043c\u0443\u044e \u0447\u0430\u0441\u0442\u044c     if let frameInRootView, visibleFrameInRootView.size != frameInRootView.size {         let cropRect = rootView.convert(visibleFrameInRootView, to: view)         snapshot = snapshot.flatMap { cropImage($0, to: cropRect) }     }     return snapshot }<\/code><\/pre>\n<p>\u0421\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u0441\u043d\u0430\u043f\u0448\u043e\u0442\u0430 \u0434\u043b\u044f \u043d\u0430\u0448\u0435\u0439 \u0444\u0438\u0447\u0438 \u0438\u043c\u0435\u0435\u0442 \u0441\u0432\u043e\u044e \u0441\u043f\u0435\u0446\u0438\u0444\u0438\u043a\u0443 \u2014 \u043c\u044b \u0434\u043e\u043b\u0436\u043d\u044b \u0434\u0435\u043b\u0430\u0442\u044c \u0441\u043d\u0430\u043f\u0448\u043e\u0442 \u0442\u043e\u043b\u044c\u043a\u043e \u0441\u0430\u043c\u043e\u0439 \u0432\u044c\u044e\u0448\u043a\u0438, \u0438\u0441\u043a\u043b\u044e\u0447\u0438\u0432 \u0432\u0441\u0435 \u0435\u0451 \u0441\u0430\u0431\u0432\u044c\u044e, \u043f\u043e\u0442\u043e\u043c\u0443 \u0447\u0442\u043e \u043e\u043d\u0438 \u0431\u0443\u0434\u0443\u0442 \u0441\u043d\u0430\u043f\u0448\u043e\u0442\u0438\u0442\u044c\u0441\u044f \u0434\u043b\u044f \u0432\u0441\u0435\u0445 \u0441\u043b\u043e\u0435\u0432 \u043f\u043e \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u0438. <\/p>\n<p>\u0418 \u043a\u0430\u043a \u0436\u0435 \u043c\u044b \u044d\u0442\u043e \u0441\u0434\u0435\u043b\u0430\u0435\u043c?<\/p>\n<p><strong>\u041c\u044b \u0441\u043a\u0440\u043e\u0435\u043c \u0432\u0441\u0435 \u0441\u0430\u0431\u0432\u044c\u044e\u0445\u0438! \u0414\u043e \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u0441\u043d\u0430\u043f\u0448\u043e\u0442\u0430. \u0410 \u043f\u043e\u0441\u043b\u0435 \u0432\u0435\u0440\u043d\u0435\u043c isHidden \u043d\u0430 \u043c\u0435\u0441\u0442\u043e.<\/strong><\/p>\n<p>\u042d\u0442\u043e \u0440\u0435\u0448\u0435\u043d\u0438\u0435 \u044f \u043f\u043e\u0434\u0441\u043c\u043e\u0442\u0440\u0435\u043b \u0432 \u0442\u0435\u0445 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0430\u0445, \u0447\u0442\u043e \u0443\u043f\u043e\u043c\u0438\u043d\u0430\u043b \u0432 \u043d\u0430\u0447\u0430\u043b\u0435. \u041f\u043b\u0430\u043d \u043d\u0430\u0434\u0435\u0436\u043d\u044b\u0439 \u043a\u0430\u043a \u0448\u0432\u0435\u0439\u0446\u0430\u0440\u0441\u043a\u0438\u0435 \u0447\u0430\u0441\u044b, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u044f \u0438 \u043d\u0435 \u043f\u0440\u0438\u0434\u0443\u043c\u0430\u043b \u043d\u0438\u0447\u0435\u0433\u043e \u043b\u0443\u0447\u0448\u0435, \u0447\u0435\u043c \u0435\u0433\u043e \u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c.<\/p>\n<p>\u041f\u0440\u0430\u0432\u0434\u0430 \u043f\u043e\u0437\u0436\u0435 \u0432\u044b\u044f\u0441\u043d\u0438\u043b\u043e\u0441\u044c, \u0447\u0442\u043e \u0438\u0437 \u0437\u0430 \u0442\u0430\u043a\u043e\u0433\u043e \u0440\u0435\u0448\u0435\u043d\u0438\u044f \u0432 UICollectionView, \u0434\u043b\u044f \u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u0434\u0435\u043b\u0430\u0435\u0442\u0441\u044f \u0441\u043d\u0430\u043f\u0448\u043e\u0442, \u043c\u043e\u0433\u0443\u0442 \u0431\u0435\u0441\u0441\u043b\u0435\u0434\u043d\u043e \u043f\u0440\u043e\u043f\u0430\u0434\u0430\u0442\u044c \u044f\u0447\u0435\u0439\u043a\u0438, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043c\u044b, \u043f\u043e\u0441\u043b\u0435 \u0442\u0430\u043a\u043e\u0433\u043e \u0431\u0435\u0441\u043f\u0440\u0438\u043d\u0446\u0438\u043f\u043d\u043e\u0433\u043e \u0434\u0435\u0431\u0430\u0433\u0433\u0438\u043d\u0433\u0430, \u0443\u0432\u0438\u0434\u0435\u0442\u044c \u0431\u043e\u043b\u044c\u0448\u0435 \u043d\u0435 \u0441\u043c\u043e\u0436\u0435\u043c.<\/p>\n<p><strong>\u0420\u0435\u0448\u0438\u043b\u0438 \u0441\u043a\u0440\u044b\u0442\u0438\u0435\u043c \u0442\u043e\u043b\u044c\u043a\u043e visibleCells \u0432 \u043a\u043e\u043b\u043b\u0435\u043a\u0446\u0438\u0438.<\/strong> <\/p>\n<pre><code class=\"swift\">func makeSnapshot(of view: UIView) -> UIImage {     var subviewsHidden: [Bool] = []     let subviews = makeFilteredSubviews(of: view)      subviewsHidden.reserveCapacity(subviews.count)     for subview in subviews {         subviewsHidden.append(subview.isHidden)         subview.isHidden = true     }     let snapshot = drawView(view)     for (subview, isHidden) in zip(subviews, subviewsHidden) {         subview.isHidden = isHidden     }     return snapshot }  func drawView(_ view: UIView) -> UIImage {     UIGraphicsImageRenderer(bounds: view.bounds).image { rendererContext in         view.layer.render(in: rendererContext.cgContext)     } }  func makeFilteredSubviews(of view: UIView) -> [UIView] {     guard let collectionView = view as? UICollectionView else {         return view.subviews     }     let visibleCells = collectionView.visibleCells     let subviews = collectionView.subviews.filter { !($0 is UICollectionViewCell) }     return subviews + visibleCells }<\/code><\/pre>\n<h2>\u0420\u0435\u0448\u0430\u0435\u043c \u043e\u0441\u0442\u0430\u0432\u0448\u0438\u0435\u0441\u044f \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u044b<\/h2>\n<figure class=\"float bordered full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/f22\/eb0\/6e9\/f22eb06e9c297e19b6c87e93a1c28c3d.png\" width=\"1546\" height=\"1548\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/f22\/eb0\/6e9\/f22eb06e9c297e19b6c87e93a1c28c3d.png\"\/><\/figure>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c, \u043c\u044b \u0441\u0444\u043e\u0440\u043c\u0438\u0440\u043e\u0432\u0430\u043b\u0438 \u043d\u0430\u0448\u0443 \u043c\u043e\u0434\u0435\u043b\u044c\u043a\u0443 \u0438 \u043c\u043e\u0436\u0435\u043c \u043e\u0442\u0441\u044b\u043b\u0430\u0442\u044c \u0435\u0451 \u043d\u0430\u043f\u0440\u044f\u043c\u0438\u043a \u0432\u043e \u0432\u044c\u044e \u0438, \u043a\u0430\u0436\u0435\u0442\u0441\u044f, \u0447\u0442\u043e \u0432\u0441\u0451 \u0433\u043e\u0442\u043e\u0432\u043e. <\/p>\n<p>\u041d\u043e \u043a\u0430\u043a \u0431\u044b \u043d\u0435 \u0442\u0430\u043a!<\/p>\n<p>\u0420\u0435\u0448\u0438\u0432 \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u044c \u0438 \u043f\u043e\u0442\u0435\u0441\u0442\u0438\u0442\u044c \u0441\u0432\u043e\u044e \u0441\u0431\u043e\u0440\u043a\u0443, \u044f \u043e\u0431\u043d\u0430\u0440\u0443\u0436\u0438\u043b:<\/p>\n<ul>\n<li>\n<p>\u0424\u0440\u0438\u0437\u044b \u043f\u0440\u0438 \u043f\u043e\u0434\u0433\u043e\u0442\u043e\u0432\u043a\u0435 \u0434\u0430\u043d\u043d\u044b\u0445.<\/p>\n<\/li>\n<li>\n<p>\u041a\u0440\u0430\u0448\u0438! \u0421 \u0432\u044b\u0432\u043e\u0434\u043e\u043c \u0442\u0435\u0445 \u0436\u0435 \u043b\u043e\u0433\u043e\u0432, \u0447\u0442\u043e \u0438 \u0434\u043b\u044f \u0442\u0435\u0441\u0442\u0438\u0440\u0443\u0435\u043c\u044b\u0445 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a.<\/p>\n<\/li>\n<li>\n<p>\u041e\u0442\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0435 \u043b\u0438\u0448\u043d\u0438\u0445 \u0432\u044c\u044e \u0432 \u0433\u0440\u0430\u0444\u0435.<\/p>\n<\/li>\n<\/ul>\n<h3>\u0420\u0435\u0448\u0430\u0435\u043c \u0434\u043e\u043b\u0433\u0443\u044e \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0443<\/h3>\n<p>\u0418\u0437-\u0437\u0430 \u0431\u043e\u043b\u044c\u0448\u043e\u0433\u043e \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u0430 \u0440\u0435\u043a\u0443\u0440\u0441\u0438\u0439 \u0440\u0430\u0441\u0447\u0451\u0442\u00a0\u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u0442\u0441\u044f \u0434\u043e\u0432\u043e\u043b\u044c\u043d\u043e \u0434\u043e\u043b\u0433\u043e. \u041a\u0430\u043a \u043f\u0440\u0430\u0432\u0438\u043b\u043e, \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u043e\u0435 \u0440\u0435\u0448\u0435\u043d\u0438\u0435 \u0442\u0430\u043a\u0438\u0445 \u043f\u0440\u043e\u0431\u043b\u0435\u043c \u2014\u00a0\u044d\u0442\u043e \u0432\u044b\u043d\u043e\u0441 \u0432 \u0431\u0435\u043a\u0433\u0440\u0430\u0443\u043d\u0434. \u041d\u043e \u043d\u0430\u0448 \u0441\u043b\u0443\u0447\u0430\u0439 \u043e\u0441\u043b\u043e\u0436\u043d\u044f\u0435\u0442\u0441\u044f \u0442\u0435\u043c, \u0447\u0442\u043e \u043c\u044b \u0432\u0437\u0430\u0438\u043c\u043e\u0434\u0435\u0439\u0441\u0442\u0432\u0443\u0435\u043c \u0441 UIView, \u0430 \u0432\u0441\u0435 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0438 \u0441 UIKit \u0434\u043e\u043b\u0436\u043d\u044b \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0442\u044c\u0441\u044f \u043d\u0430 main \u043e\u0447\u0435\u0440\u0435\u0434\u0438.<\/p>\n<p>\u041d\u043e \u0440\u0435\u0448\u0435\u043d\u0438\u0435 \u0434\u043e\u0432\u043e\u043b\u044c\u043d\u043e \u043f\u0440\u043e\u0441\u0442\u043e\u0435 \u2014 \u044f \u043e\u0431\u0435\u0440\u043d\u0443\u043b \u0432\u0441\u0451 \u0432 Promise (\u043d\u0430 \u043f\u0440\u043e\u0435\u043a\u0442\u0435 \u043c\u044b \u043f\u043e\u0432\u0441\u0435\u043c\u0435\u0441\u0442\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c PromiseKit)! \u042d\u0442\u043e \u0440\u0430\u0432\u043d\u043e\u0441\u0438\u043b\u044c\u043d\u043e \u0442\u043e\u043c\u0443, \u0447\u0442\u043e\u0431\u044b \u0432\u044b\u0437\u044b\u0432\u0430\u0442\u044c \u0431\u043b\u043e\u043a \u043a\u043e\u0434\u0430 \u0432 <code>DispatchQueue.main.async<\/code>.<\/p>\n<p><strong>\u0414\u0430, \u043c\u044b \u043d\u0435 \u043f\u0435\u0440\u0435\u043d\u043e\u0441\u0438\u043c \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u0435 \u0432 \u0431\u0435\u043a\u0433\u0440\u0430\u0443\u043d\u0434 \u0438 \u0431\u043b\u043e\u043a\u0438\u0440\u0443\u0435\u043c UI.<\/strong> \u041d\u043e \u0432\u0438\u0437\u0443\u0430\u043b\u044c\u043d\u043e \u043c\u044b \u043d\u0438\u0447\u0435\u0433\u043e \u043d\u0435 \u0444\u0440\u0438\u0437\u0438\u043c \u0438 \u043f\u0435\u0440\u0435\u043d\u043e\u0441\u0438\u043c \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u0435 \u0440\u0430\u0441\u0447\u0451\u0442\u043e\u0432 \u043d\u0430 \u0442\u043e\u0442 \u043c\u043e\u043c\u0435\u043d\u0442, \u043a\u043e\u0433\u0434\u0430 \u043d\u0430 \u0433\u043b\u0430\u0432\u043d\u043e\u043c \u043f\u043e\u0442\u043e\u043a\u0435 \u0443\u0436\u0435 \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0442\u0441\u044f \u0434\u0440\u0443\u0433\u0438\u0435 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0438 \u2014 \u043d\u043e\u0440\u043c\u0430\u043b\u044c\u043d\u043e \u043e\u0442\u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u043f\u0443\u0448 \u0443 \u043d\u0430\u0432\u0438\u0433\u0435\u0439\u0448\u043d \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440\u0430 \u0438 \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u044c\u0441\u044f \u0441\u043f\u0438\u043d\u043d\u0435\u0440. <\/p>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u0443 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u0439 \u043d\u0435 \u0432\u043e\u0437\u043d\u0438\u043a\u043d\u0435\u0442 \u043e\u0449\u0443\u0449\u0435\u043d\u0438\u044f \u00ab\u0447\u0442\u043e-\u0442\u043e \u043d\u0435 \u0442\u043e\u00bb \u0438 \u043e\u043d\u0438, \u0432\u0435\u0440\u043e\u044f\u0442\u043d\u043e, \u043d\u0435 \u0437\u0430\u043c\u0435\u0442\u044f\u0442 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u044b. <\/p>\n<pre><code class=\"swift\">func getViewHierarchy() -> Promise&lt;[VisualDebugger.LayoutModel]> {     Promise { [weak self] resolver in         guard let self, let rootView = self.rootView else {             resolver.fulfill([])             return         }         var depth: Float = Configuration.startDepth         let result = self.getLayoutModelsRecursively(for: rootView, rootView: rootView, depth: &amp;depth)         resolver.fulfill(result)     } }<\/code><\/pre>\n<h3>\u0418\u0437\u0431\u0430\u0432\u043b\u044f\u0435\u043c\u0441\u044f \u043e\u0442 \u043a\u0440\u0430\u0448\u0435\u0439<\/h3>\n<p>\u0412\u043e \u0432\u0440\u0435\u043c\u044f \u0442\u0435\u0441\u0442\u043e\u0432 \u044f \u043e\u0431\u043d\u0430\u0440\u0443\u0436\u0438\u043b, \u0447\u0442\u043e \u0435\u0441\u043b\u0438 \u043c\u044b \u043e\u0442\u043a\u0440\u043e\u0435\u043c \u043d\u0430\u0448 VisualDebugger \u0434\u043b\u044f \u0441\u0442\u0435\u043a \u0432\u044c\u044e, \u0432 \u043a\u043e\u0442\u043e\u0440\u043e\u043c \u043b\u0435\u0436\u0438\u0442 \u0432\u0435\u0441\u044c \u043a\u043e\u043d\u0442\u0435\u043d\u0442 \u0433\u043b\u0430\u0432\u043d\u043e\u0433\u043e \u044d\u043a\u0440\u0430\u043d\u0430, \u0442\u043e \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u043a\u0440\u0430\u0448\u0438\u0442\u0441\u044f \u0441 \u043d\u0438\u0436\u0435\u043b\u0435\u0436\u0430\u0449\u0435\u0439 \u043e\u0448\u0438\u0431\u043a\u043e\u0439.<\/p>\n<p><code>-[MTLTextureDescriptorInternalvalidateWithDevice:], line 1325: error 'Texture Descriptor Validation MTLTextureDescriptor has height (8334) greater than the maximum allowed size of 8192'<\/code><\/p>\n<p>\u042d\u0442\u0430 \u043e\u0448\u0438\u0431\u043a\u0430 \u043b\u0435\u0442\u0438\u0442 \u043a \u043d\u0430\u043c \u043f\u0440\u044f\u043c\u0438\u043a\u043e\u043c \u0438\u0437 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438 Metal, \u043f\u043e\u0432\u0435\u0440\u0445 \u043a\u043e\u0442\u043e\u0440\u043e\u0439 \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 SceneKit. \u0418 \u0432\u0435\u0449\u0430\u0435\u0442 \u043e\u043d\u0430 \u043d\u0430\u043c \u043e \u0442\u043e\u043c, \u0447\u0442\u043e \u0440\u0430\u0437\u043c\u0435\u0440 \u0442\u043e\u0439 \u0442\u0435\u043a\u0441\u0442\u0443\u0440\u044b, \u043a\u043e\u0442\u043e\u0440\u0443\u044e \u043c\u044b \u043f\u0440\u0438\u0441\u0432\u0430\u0438\u0432\u0430\u0435\u043c \u0432 \u043c\u0430\u0442\u0435\u0440\u0438\u0430\u043b, \u043f\u0440\u0435\u0432\u044b\u0448\u0430\u0435\u0442 \u043c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u044c\u043d\u043e\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435.<\/p>\n<p><a href=\"https:\/\/developer.apple.com\/forums\/thread\/721046\">\u041d\u0430\u0439\u0434\u044f \u0442\u0440\u0435\u0434<\/a> \u043d\u0430 <a href=\"https:\/\/developer.apple.com\/forums\/thread\/721046\"><u>developer.apple<\/u><\/a><u>,<\/u> \u044f \u0432\u044b\u0448\u0435\u043b \u043d\u0430 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0443\u044e \u0442\u0430\u0431\u043b\u0438\u0446\u0443, \u0432 \u043a\u043e\u0442\u043e\u0440\u043e\u0439 \u0433\u043e\u0432\u043e\u0440\u0438\u0442\u0441\u044f, \u0447\u0442\u043e <code>GPUFamily<\/code> \u2014 \u044d\u0442\u043e \u0433\u0440\u0443\u043f\u043f\u0430 \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432, \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u044e\u0449\u0438\u0445 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u043d\u044b\u0435 \u0444\u0438\u0447\u0438 Metal-a, \u0438 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0435\u0442\u0441\u044f \u044d\u0442\u0430 \u0433\u0440\u0443\u043f\u043f\u0430 \u043f\u043e \u043f\u0440\u043e\u0446\u0435\u0441\u0441\u043e\u0440\u0443, \u0430 \u043c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u044c\u043d\u044b\u0439 \u0440\u0430\u0437\u043c\u0435\u0440 \u0442\u0435\u043a\u0441\u0442\u0443\u0440\u044b \u2014 \u044d\u0442\u043e \u043e\u0434\u043d\u0430 \u0438\u0437 \u0444\u0438\u0447\u0435\u0439. <\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/416\/5e7\/7a7\/4165e77a7a0071b9d397715267a72516.png\" alt=\"\" title=\"\" width=\"1600\" height=\"232\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/416\/5e7\/7a7\/4165e77a7a0071b9d397715267a72516.png\"\/><\/figure>\n<p>\u042f \u043d\u0435 \u0441\u0442\u0430\u043b \u0443\u0441\u043b\u043e\u0436\u043d\u044f\u0442\u044c \u0441\u0435\u0431\u0435 \u0436\u0438\u0437\u043d\u044c \u0442\u0435\u043c, \u0447\u0442\u043e\u0431\u044b \u0432\u044b\u0442\u0430\u0449\u0438\u0442\u044c \u043d\u0443\u0436\u043d\u044b\u0439 GPUFamily \u0438 \u043f\u043e \u043d\u0435\u043c\u0443 \u043e\u0442\u0434\u0430\u0432\u0430\u0442\u044c \u043c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u044c\u043d\u044b\u0439 \u0440\u0430\u0437\u043c\u0435\u0440, \u0430 \u043f\u0440\u043e\u0441\u0442\u043e \u0441\u0445\u043e\u0434\u0443 \u043f\u043e\u0441\u0442\u0430\u0432\u0438\u043b \u043c\u0438\u043d\u0438\u043c\u0430\u043b\u044c\u043d\u044b\u0439 \u0440\u0430\u0437\u043c\u0435\u0440.<\/p>\n<pre><code class=\"swift\">struct VisualDebuggerViewImageReducer: ReducesVisualDebuggerViewImage {     func reduceImageIfNeeded(_ image: UIImage) -> UIImage {         let scaledHeight = image.size.height * image.scale         let scaledWidth = image.size.width * image.scale         guard scaledHeight > 8_192 || scaledWidth > 8_192 else { return image }         let scaleFactor = min(8_192 \/ scaledWidth, 8_192 \/ scaledHeight)         let newSize = CGSize(             width: image.size.width * scaleFactor,             height: image.size.height * scaleFactor         )         return UIGraphicsImageRenderer(size: newSize).image { _ in             image.draw(in: CGRect(origin: .zero, size: newSize))         }     } }<\/code><\/pre>\n<h3>\u041b\u0438\u0448\u043d\u0438\u0435 \u0432\u044c\u044e \u0432 \u0438\u0435\u0440\u0430\u0440\u0445\u0438\u0438<\/h3>\n<p>\u0422\u0430\u043a \u043a\u0430\u043a \u043d\u0430\u0448\u0435 DebugMenu \u043f\u0440\u0435\u0437\u0435\u043d\u0442\u0438\u0442\u0441\u044f \u0438 \u043f\u0440\u0438\u0441\u0443\u0442\u0441\u0442\u0432\u0443\u0435\u0442 \u0432 \u0438\u0435\u0440\u0430\u0440\u0445\u0438\u0438 \u043d\u0430 \u043c\u043e\u043c\u0435\u043d\u0442 \u043f\u043e\u0441\u0442\u0440\u043e\u0435\u043d\u0438\u044f \u0433\u0440\u0430\u0444\u0430, \u043c\u044b \u043f\u0440\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u043c \u0434\u043b\u044f \u0432\u044c\u044e NavigationController-a \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u043d\u044b\u0439 \u0442\u044d\u0433, \u043f\u043e \u043a\u043e\u0442\u043e\u0440\u043e\u043c\u0443 \u043f\u0440\u043e\u0432\u0430\u0439\u0434\u0435\u0440 \u043f\u043e\u043d\u0438\u043c\u0430\u0435\u0442, \u0447\u0442\u043e \u0434\u043b\u044f \u0434\u0430\u043d\u043d\u043e\u0439 \u0432\u044c\u044e \u0438 \u0435\u0435 \u0441\u0430\u0431\u0432\u044c\u044e \u0441\u0442\u0440\u043e\u0438\u0442\u044c \u0432\u0438\u0437\u0443\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044e \u043d\u0435 \u043d\u0443\u0436\u043d\u043e. <br \/>\u041d\u043e \u044d\u0442\u043e\u0433\u043e \u043e\u043a\u0430\u0437\u0430\u043b\u043e\u0441\u044c \u043d\u0435\u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e, \u0442\u0430\u043a \u043a\u0430\u043a \u043e\u0431\u043d\u0430\u0440\u0443\u0436\u0435\u043d\u043d\u0430\u044f \u0432\u044c\u044e \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f TransitionView \u0434\u043b\u044f NavigationController. <\/p>\n<p>\u041c\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c <a href=\"https:\/\/github.com\/ekazaev\/route-composer\">RouteComposer<\/a>, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u043f\u043e\u043b\u0443\u0447\u0438\u043b\u043e\u0441\u044c \u0438\u0441\u043f\u0440\u0430\u0432\u0438\u0442\u044c \u044d\u0442\u043e\u0442 \u043c\u043e\u043c\u0435\u043d\u0442 \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f PostRoutingTask \u0434\u043b\u044f \u0440\u043e\u0443\u0442\u0430 \u0432\u0435\u0434\u0443\u0449\u0435\u0433\u043e \u043d\u0430 DebugMenu, \u0433\u0434\u0435 CompletionPostRoutingTask \u2014 \u044d\u0442\u043e \u0437\u0430\u043c\u044b\u043a\u0430\u043d\u0438\u0435, \u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u0442\u0441\u044f \u043f\u043e\u0441\u043b\u0435 \u0442\u043e\u0433\u043e, \u043a\u0430\u043a \u0440\u043e\u0443\u0442\u0438\u043d\u0433 \u043e\u0442\u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442.<\/p>\n<pre><code class=\"swift\">return SharedRouter.Route { completion in     try? RCRouter().navigate(         to: StepAssembly(             finder: DebugMenuListFactory&lt;Self>.DefaultFinderByClassName(), factory: DebugMenuListFactory&lt;Self>()         )         .adding(             ClosePostRoutingTask&lt;DebugMenuListFactory&lt;Self>.ViewController, DebugMenuListFactory&lt;Self>.Context>(                 closeBarButtonItemSide: .right             )         )         .adding(             CompletionPostRoutingTask&lt;DebugMenuListFactory&lt;Self>.ViewController, DebugMenuListFactory&lt;Self>.Context> {                 \/\/ \u0423\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u0435\u043c \u0442\u0435\u0433 \u043d\u0430 \u0432\u044c\u044e \u0434\u043b\u044f \u0444\u0438\u043b\u044c\u0442\u0440\u0430\u0446\u0438\u0438 \u0434\u0435\u0431\u0430\u0433 \u043c\u0435\u043d\u044e \u0432 \u0438\u0435\u0440\u0430\u0440\u0445\u0438\u0438 \u0432\u044c\u044e\u0445                 $0.navigationController?.presentationController?.containerView?.tag = rootDebugMenuViewTag             }         )         .wrapAlertInContainer(             wrapperFactory: AlfaNavigationControllerFactory {                 $0.additionalSafeAreaInsets = CustomScreenSizeDataStore.shared.currentAdditionalSafeAreaInsets                 \/\/ \u0423\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u0435\u043c \u0442\u0435\u0433 \u043d\u0430 \u0432\u044c\u044e \u0434\u043b\u044f \u0444\u0438\u043b\u044c\u0442\u0440\u0430\u0446\u0438\u0438 \u0434\u0435\u0431\u0430\u0433 \u043c\u0435\u043d\u044e \u0432 \u0438\u0435\u0440\u0430\u0440\u0445\u0438\u0438 \u0432\u044c\u044e\u0445                 $0.view.tag = rootDebugMenuViewTag             }         )         .using(GeneralAction.presentModally(presentationStyle: .overFullScreen))         .from(GeneralStep.current()).assemble(),         with: .init(screenTitle: title, navigationElements: .title, sectionProviders: currentSectionProviders),         completion: completion     ) }<\/code><\/pre>\n<h2>\u0417\u0430\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435 <\/h2>\n<p>\u041f\u0440\u0438\u0448\u043b\u043e \u0432\u0440\u0435\u043c\u044f \u043f\u043e\u0434\u0432\u0435\u0441\u0442\u0438 \u0438\u0442\u043e\u0433\u0438. <\/p>\n<blockquote>\n<p>\u0418\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435 FLEX \u0438 \u043f\u043e\u0434\u043e\u0431\u043d\u044b\u0445 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a \u0434\u043b\u044f \u043e\u0442\u043b\u0430\u0434\u043a\u0438 \u0443\u043f\u0440\u043e\u0449\u0430\u0435\u0442 \u0438 \u0443\u0441\u043a\u043e\u0440\u044f\u0435\u0442 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0443, \u043d\u043e \u044d\u0442\u043e \u043d\u0435 \u0443\u043d\u0438\u0432\u0435\u0440\u0441\u0430\u043b\u044c\u043d\u043e\u0435 \u0440\u0435\u0448\u0435\u043d\u0438\u0435 \u0434\u043b\u044f \u0432\u0441\u0435\u0445 \u0437\u0430\u0434\u0430\u0447. <\/p>\n<\/blockquote>\n<p>\u041c\u043e\u044f \u0440\u0430\u0431\u043e\u0442\u0430 \u043f\u043e\u043a\u0430\u0437\u0430\u043b\u0430, \u0447\u0442\u043e \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0430 \u0438 \u0430\u0434\u0430\u043f\u0442\u0430\u0446\u0438\u044f \u0442\u0430\u043a\u0438\u0445 \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u043e\u0432 \u043f\u043e\u0434 \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u044b\u0435 \u043d\u0443\u0436\u0434\u044b \u043f\u0440\u043e\u0435\u043a\u0442\u0430 \u043c\u043e\u0433\u0443\u0442 \u043f\u043e\u0442\u0440\u0435\u0431\u043e\u0432\u0430\u0442\u044c \u0437\u043d\u0430\u0447\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0445 \u0443\u0441\u0438\u043b\u0438\u0439. \u0412 \u0438\u0442\u043e\u0433\u0435, \u043c\u044b \u043f\u043e\u043b\u0443\u0447\u0438\u043b\u0438 \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043d\u0435 \u0442\u043e\u043b\u044c\u043a\u043e \u0443\u0441\u0442\u0440\u0430\u043d\u044f\u0435\u0442 \u043e\u0431\u0449\u0438\u0435 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u044b, \u043d\u043e \u0438 \u0430\u0434\u0430\u043f\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0439 \u043f\u043e\u0434 \u0441\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u044b\u0435 \u0443\u043d\u0438\u043a\u0430\u043b\u044c\u043d\u044b\u0435 \u0443\u0441\u043b\u043e\u0432\u0438\u044f.<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/247\/6a1\/bfd\/2476a1bfdbf73a1f715eb59361b8c1f4.png\" width=\"1740\" height=\"1600\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/247\/6a1\/bfd\/2476a1bfdbf73a1f715eb59361b8c1f4.png\"\/><\/figure>\n<div class=\"tm-iframe_temp\" data-src=\"https:\/\/embedd.srv.habr.com\/iframe\/6566079e72e08276d7ce7a7d\" data-style=\"\" id=\"6566079e72e08276d7ce7a7d\" width=\"\"><\/div>\n<p>\u041e\u0442\u0434\u0435\u043b\u044c\u043d\u043e \u0441\u0442\u043e\u0438\u0442 \u0443\u043f\u043e\u043c\u044f\u043d\u0443\u0442\u044c \u043e\u043f\u044b\u0442 \u0440\u0430\u0431\u043e\u0442\u044b \u0441 SceneKit. \u041d\u0435\u0441\u043c\u043e\u0442\u0440\u044f \u043d\u0430 \u043e\u0436\u0438\u0434\u0430\u043d\u0438\u044f, \u0447\u0442\u043e \u0432\u0441\u0442\u0440\u043e\u0438\u0442\u044c \u0442\u0440\u0435\u0445\u043c\u0435\u0440\u043d\u0443\u044e \u0432\u0438\u0437\u0443\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044e \u0431\u0443\u0434\u0435\u0442 \u0441\u043b\u043e\u0436\u043d\u043e, \u044d\u0442\u043e\u0442 \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442 \u043e\u043a\u0430\u0437\u0430\u043b\u0441\u044f \u0434\u0440\u0443\u0436\u0435\u043b\u044e\u0431\u043d\u044b\u043c \u0438 \u0433\u0438\u0431\u043a\u0438\u043c. \u0412 \u043a\u043e\u0440\u043e\u0442\u043a\u0438\u0435 \u0441\u0440\u043e\u043a\u0438 \u0443\u0434\u0430\u043b\u043e\u0441\u044c \u0434\u043e\u0441\u0442\u0438\u0447\u044c \u0432\u043f\u0435\u0447\u0430\u0442\u043b\u044f\u044e\u0449\u0438\u0445 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u043e\u0432! \u0422\u0435\u043c \u043d\u0435 \u043c\u0435\u043d\u0435\u0435, \u043d\u0435 \u0441\u0442\u043e\u0438\u0442 \u0437\u0430\u0431\u044b\u0432\u0430\u0442\u044c \u043e \u043f\u043e\u0442\u0435\u043d\u0446\u0438\u0430\u043b\u044c\u043d\u044b\u0445 \u0440\u0438\u0441\u043a\u0430\u0445: \u043d\u0435\u043e\u0436\u0438\u0434\u0430\u043d\u043d\u044b\u0435 \u043e\u0448\u0438\u0431\u043a\u0438 \u0438 \u043f\u043e\u0434\u0432\u043e\u0434\u043d\u044b\u0435 \u043a\u0430\u043c\u043d\u0438 \u043c\u043e\u0433\u0443\u0442 \u043f\u043e\u0434\u0441\u0442\u0435\u0440\u0435\u0433\u0430\u0442\u044c \u043d\u0430\u0441 \u043d\u0430 \u043b\u044e\u0431\u043e\u043c \u044d\u0442\u0430\u043f\u0435 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0438.<\/p>\n<\/p>\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\/775186\/\"> https:\/\/habr.com\/ru\/articles\/775186\/<\/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-2\">\n<div xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\">\n<p><strong>\u041f\u0440\u0438\u043c\u0435\u0447\u0430\u043d\u0438\u0435<\/strong>. \u042d\u0442\u0430 \u0441\u0442\u0430\u0442\u044c\u044f \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0434\u043e\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u0435\u043c \u043a \u0441\u0442\u0430\u0442\u044c\u0435 <a href=\"https:\/\/habr.com\/ru\/companies\/alfa\/articles\/763596\/\">\u0414\u0435\u0431\u0430\u0433\u0433\u0438\u043d\u0433 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u0431\u0435\u0437 Xcode. \u0417\u0430\u0447\u0435\u043c?<\/a><\/p>\n<p>\u0412 \u043d\u0430\u0447\u0430\u043b\u0435 \u043a\u0432\u0430\u0440\u0442\u0430\u043b\u0430, \u0432 \u0410\u043b\u044c\u0444\u0435, \u043c\u044b \u0432\u044b\u0431\u0438\u0440\u0430\u0435\u043c \u0441\u0435\u0431\u0435 \u0442\u0435\u0445\u043d\u0438\u0447\u0435\u0441\u043a\u0438\u0435 \u0442\u0430\u0441\u043a\u0438 \u2014 \u0437\u0430\u0434\u0430\u0447\u0438, \u043d\u0430\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u043d\u044b\u0435 \u043d\u0430 \u0442\u0435\u0445\u043d\u0438\u0447\u0435\u0441\u043a\u043e\u0435 \u0440\u0430\u0437\u0432\u0438\u0442\u0438\u0435 \u043f\u0440\u043e\u0435\u043a\u0442\u0430, \u0430 \u043d\u0435 \u043d\u0430 \u043f\u0440\u043e\u0434\u0443\u043a\u0442\u043e\u0432\u0443\u044e \u0441\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u044e\u0449\u0443\u044e. \u041f\u0440\u0438 \u0432\u044b\u0431\u043e\u0440\u0435 \u0437\u0430\u0434\u0430\u0447\u0438 \u0445\u043e\u0447\u0435\u0442\u0441\u044f, \u0447\u0442\u043e\u0431\u044b \u043e\u043d\u0430 \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u043e\u0432\u0430\u043b\u0430 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u0438\u043c \u0443\u0441\u043b\u043e\u0432\u0438\u044f\u043c:<\/p>\n<ul>\n<li>\n<p>\u0440\u0435\u0448\u0430\u0435\u0442 \u0440\u0435\u0430\u043b\u044c\u043d\u044b\u0435 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u044b \u043d\u0430\u0448\u0435\u0439 \u043a\u043e\u043c\u0430\u043d\u0434\u044b, \u0443\u043f\u0440\u043e\u0449\u0430\u044f \u0435\u0436\u0435\u0434\u043d\u0435\u0432\u043d\u0443\u044e \u0440\u0430\u0431\u043e\u0442\u0443;<\/p>\n<\/li>\n<li>\n<p>\u0443\u043a\u043b\u0430\u0434\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u0432 \u0447\u0435\u0442\u044b\u0440\u0435 \u0432\u044b\u0434\u0435\u043b\u0435\u043d\u043d\u044b\u0445 \u0442\u0435\u0445\u043d\u0438\u0447\u0435\u0441\u043a\u0438\u0445 \u0434\u043d\u044f \u2014 \u043d\u0430\u0448 \u0444\u043e\u0440\u043c\u0430\u0442 \u0440\u0430\u0431\u043e\u0442\u044b \u043f\u0440\u0435\u0434\u043f\u043e\u043b\u0430\u0433\u0430\u0435\u0442 \u0432\u044b\u0431\u043e\u0440 \u0442\u0440\u0435\u0445 \u0437\u0430\u0434\u0430\u0447 \u043d\u0430 \u043a\u0432\u0430\u0440\u0442\u0430\u043b \u0438 \u0438\u0445 \u0440\u0435\u0448\u0435\u043d\u0438\u0435 \u0432 \u0442\u0435\u0447\u0435\u043d\u0438\u0435 20% \u0440\u0430\u0431\u043e\u0447\u0435\u0433\u043e \u0432\u0440\u0435\u043c\u0435\u043d\u0438;<\/p>\n<\/li>\n<li>\n<p>\u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u0440\u0430\u0441\u0442\u0438 \u043f\u0440\u043e\u0444\u0435\u0441\u0441\u0438\u043e\u043d\u0430\u043b\u044c\u043d\u043e, \u0434\u0430\u0432\u0430\u044f \u0448\u0430\u043d\u0441 \u043f\u043e\u0433\u0440\u0443\u0437\u0438\u0442\u044c\u0441\u044f \u0432 \u043d\u043e\u0432\u044b\u0435 \u0442\u0435\u0445\u043d\u043e\u043b\u043e\u0433\u0438\u0438 \u0438 \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u044b.<\/p>\n<\/li>\n<\/ul>\n<figure class=\"full-width\"><\/figure>\n<p>\u0421\u0440\u0435\u0434\u0438 \u0442\u0435\u0445\u043d\u0438\u0447\u0435\u0441\u043a\u0438\u0445 \u0437\u0430\u0434\u0430\u0447 \u043c\u043e\u0435 \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u0435 \u043f\u0440\u0438\u0432\u043b\u0435\u043a\u043b\u0430 \u0437\u0430\u0434\u0430\u0447\u0430 \u043f\u043e \u0432\u0438\u0437\u0443\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u0438\u0435\u0440\u0430\u0440\u0445\u0438\u0438 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u043e\u0432 \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u0430. \u041e\u043d\u0430 \u043a\u0430\u0437\u0430\u043b\u0430\u0441\u044c \u043c\u043d\u0435 \u0438\u0434\u0435\u0430\u043b\u044c\u043d\u043e\u0439: \u043f\u043e\u043c\u0438\u043c\u043e \u043e\u0447\u0435\u0432\u0438\u0434\u043d\u043e\u0439 \u043f\u043e\u043b\u044c\u0437\u044b \u0434\u043b\u044f \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u043e\u0432, \u043a\u043e\u0442\u043e\u0440\u044b\u043c \u043d\u0435 \u0432\u0441\u0435\u0433\u0434\u0430 \u0443\u0434\u043e\u0431\u043d\u043e \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u0441 View Hierarchy \u0432 Xcode (\u0432 \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u0441\u043b\u0443\u0447\u0430\u044f\u0445, \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044f \u0443 \u0432\u044c\u044e \u043e\u0442\u0441\u0443\u0442\u0441\u0442\u0432\u0443\u044e\u0442), \u0438 \u043d\u0435\u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e \u043f\u0440\u0438 \u0441\u0431\u043e\u0440\u043a\u0430\u0445 \u0447\u0435\u0440\u0435\u0437 AppCenter \u0438\u043b\u0438 TestFlight, \u0437\u0430\u0434\u0430\u0447\u0430 \u043e\u0431\u0435\u0449\u0430\u043b\u0430 \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u044b\u0435 \u0432\u044b\u0437\u043e\u0432\u044b \u2014 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u043f\u043e\u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u0441 SceneKit. \u041a \u0442\u043e\u043c\u0443 \u0436\u0435, \u043d\u0430\u043b\u0438\u0447\u0438\u0435 \u043e\u0442\u043a\u0440\u044b\u0442\u044b\u0445 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a, \u0440\u0435\u0448\u0430\u044e\u0449\u0438\u0445 \u043f\u043e\u0434\u043e\u0431\u043d\u044b\u0435 \u0437\u0430\u0434\u0430\u0447\u0438, \u043f\u0440\u0435\u0434\u043f\u043e\u043b\u0430\u0433\u0430\u043b\u043e \u043b\u0435\u0433\u043a\u043e\u0441\u0442\u044c \u0438\u043d\u0442\u0435\u0433\u0440\u0430\u0446\u0438\u0438 \u0432 \u043d\u0430\u0448 \u043f\u0440\u043e\u0435\u043a\u0442.<\/p>\n<figure class=\"full-width\">\n<div><figcaption>\u0413\u043b\u0430\u0432\u043d\u044b\u0439 \u044d\u043a\u0440\u0430\u043d \u0432\u043e View Hierarchy<\/figcaption><\/div>\n<\/figure>\n<p>\u041e\u0434\u043d\u0430\u043a\u043e, \u043a\u0430\u043a \u0447\u0430\u0441\u0442\u043e \u0431\u044b\u0432\u0430\u0435\u0442 \u0432 \u043c\u0438\u0440\u0435 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0438, \u043f\u0435\u0440\u0432\u043e\u043d\u0430\u0447\u0430\u043b\u044c\u043d\u044b\u0435 \u043e\u0436\u0438\u0434\u0430\u043d\u0438\u044f \u0440\u0430\u0437\u043e\u0448\u043b\u0438\u0441\u044c \u0441 \u0440\u0435\u0430\u043b\u044c\u043d\u043e\u0441\u0442\u044c\u044e. \u0412 \u044d\u0442\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0435 \u044f \u0445\u043e\u0447\u0443 \u043f\u043e\u0434\u0435\u043b\u0438\u0442\u044c\u0441\u044f \u043e\u043f\u044b\u0442\u043e\u043c, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043f\u043e\u043b\u0443\u0447\u0438\u043b, \u0440\u0430\u0437\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u044f \u0438 \u0432\u043d\u0435\u0434\u0440\u044f\u044f \u044d\u0442\u0443 \u0444\u0438\u0447\u0443, \u0440\u0430\u0441\u0441\u043a\u0430\u0437\u0430\u0442\u044c \u043e \u0442\u0435\u0445\u043d\u0438\u0447\u0435\u0441\u043a\u0438\u0445 \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u043e\u0441\u0442\u044f\u0445 \u0438 \u043e \u0442\u043e\u043c, \u043f\u043e\u0447\u0435\u043c\u0443 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435 \u043e\u0442\u0440\u044b\u0442\u044b\u0445 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a \u043c\u043e\u0436\u0435\u0442 \u043e\u043a\u0430\u0437\u0430\u0442\u044c\u0441\u044f \u043d\u0435 \u0441\u0430\u043c\u044b\u043c \u043f\u0440\u043e\u0441\u0442\u044b\u043c \u0434\u0435\u043b\u043e\u043c.<\/p>\n<h2>\u0418\u0437\u0443\u0447\u0430\u0435\u043c \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u0435 \u0440\u0435\u0448\u0435\u043d\u0438\u044f<\/h2>\n<p>\u041d\u0430\u0447\u0430\u043b \u044f \u0441 \u0438\u0437\u0443\u0447\u0435\u043d\u0438\u044f \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u0445 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a \u0438 \u043e\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u043b\u0441\u044f \u043d\u0430:<\/p>\n<ul>\n<li>\n<p><a href=\"https:\/\/github.com\/FLEXTool\/FLEX\">Flex<\/a> \u2014 \u043d\u0430\u0432\u0435\u0440\u043d\u043e\u0435, \u0441\u0430\u043c\u0430\u044f \u043f\u043e\u043f\u0443\u043b\u044f\u0440\u043d\u0430\u044f \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0430 \u0434\u043b\u044f \u0434\u0435\u0431\u0430\u0433\u0430 \u043d\u0430 iOS.<\/p>\n<\/li>\n<li>\n<p><a href=\"https:\/\/github.com\/indragiek\/InAppViewDebugger\">InAppViewDebugger<\/a> \u2014 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0430 \u043a\u0430\u043a \u0440\u0430\u0437 \u043f\u0440\u043e \u043c\u043e\u044e \u0444\u0438\u0447\u0443: \u043c\u043d\u043e\u0433\u043e \u0437\u0432\u0435\u0437\u0434\u043e\u0447\u0435\u043a \u043d\u0430 GitHub, \u0438 \u0432 Readme Flex-\u0430 \u0433\u043e\u0432\u043e\u0440\u0438\u0442\u0441\u044f \u043e \u043d\u0435\u0439, \u043a\u0430\u043a \u043e\u0431 \u043e\u0434\u043d\u043e\u043c \u0438\u0437 \u0440\u0435\u0444\u0435\u0440\u0435\u043d\u0441\u043e\u0432.<\/p>\n<\/li>\n<li>\n<p><a href=\"https:\/\/github.com\/nikitabelopotapov\/Glance\">Glance<\/a> \u2014 \u043d\u0435 \u0442\u0430\u043a\u0430\u044f \u043f\u043e\u043f\u0443\u043b\u044f\u0440\u043d\u0430\u044f \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0430, \u043d\u043e \u0441\u043e \u0441\u0445\u043e\u0436\u0438\u043c \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b\u043e\u043c.<\/p>\n<figure class=\"full-width\">\n<div><figcaption>\u041e\u0436\u0438\u0434\u0430\u0435\u043c\u044b\u0439 \u043f\u043b\u0430\u043d \u0440\u0430\u0431\u043e\u0442<\/figcaption><\/div>\n<\/figure>\n<\/li>\n<\/ul>\n<p>\u041d\u043e \u043f\u0440\u0435\u0434\u0432\u0430\u0440\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u0440\u0435\u0448\u0438\u043b \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0438\u0442\u044c \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438 \u043a \u043d\u0430\u0448\u0435\u043c\u0443 \u043f\u0440\u043e\u0435\u043a\u0442\u0443 \u0438 \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c, \u043a\u0430\u043a \u043e\u043d\u0438 \u0431\u0443\u0434\u0443\u0442 \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c. \u0418 \u0442\u0443\u0442 \u043c\u0435\u043d\u044f \u0436\u0434\u0430\u043b\u0438 \u043d\u0435\u043f\u0440\u0438\u044f\u0442\u043d\u044b\u0435 \u0441\u044e\u0440\u043f\u0440\u0438\u0437\u044b.<\/p>\n<p>\u041f\u043e\u043f\u0440\u043e\u0431\u043e\u0432\u0430\u043b \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u044c Flex \u043d\u0430 \u0433\u043b\u0430\u0432\u043d\u043e\u043c \u044d\u043a\u0440\u0430\u043d\u0435 \u0438 \u0443\u0432\u0438\u0434\u0435\u043b \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u043c\u043d\u043e\u0433\u043e \u043d\u0435\u043f\u0440\u0438\u044f\u0442\u043d\u044b\u0445 \u043c\u043e\u043c\u0435\u043d\u0442\u043e\u0432. <\/p>\n<ul>\n<li>\n<p>\u0412\u043e-\u043f\u0435\u0440\u0432\u044b\u0445, \u0432\u044c\u044e\u0448\u043a\u0438 \u043d\u0435 \u043e\u0431\u0440\u0435\u0437\u0430\u044e\u0442\u0441\u044f \u043f\u043e \u043e\u0431\u043b\u0430\u0441\u0442\u0438 \u0432\u0438\u0434\u0438\u043c\u043e\u0441\u0442\u0438, \u0447\u0442\u043e, \u043a\u0430\u043a \u043c\u043d\u0435 \u043f\u043e\u043a\u0430\u0437\u0430\u043b\u043e\u0441\u044c, \u043d\u0430\u043c \u043d\u0435 \u043f\u043e\u0434\u0445\u043e\u0434\u0438\u0442. <\/p>\n<\/li>\n<li>\n<p>\u0412\u043e-\u0432\u0442\u043e\u0440\u044b\u0445 \u2014 \u043c\u043d\u043e\u0436\u0435\u0441\u0442\u0432\u043e \u0430\u0440\u0442\u0435\u0444\u0430\u043a\u0442\u043e\u0432. \u0412 \u043e\u0431\u0449\u0435\u043c \u0438 \u0446\u0435\u043b\u043e\u043c \u0432\u0438\u0434\u043d\u043e, \u0447\u0442\u043e \u0432\u0441\u0451 \u043d\u0435 \u043e\u0447\u0435\u043d\u044c \u0445\u043e\u0440\u043e\u0448\u043e. <\/p>\n<\/li>\n<li>\n<p>\u0418, \u0432-\u0442\u0440\u0435\u0442\u044c\u0438\u0445, \u0431\u0430\u0440\u0430\u0431\u0430\u043d\u043d\u0430\u044f \u0434\u0440\u043e\u0431\u044c\u2026 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u043a\u0440\u0430\u0448\u0438\u0442\u0441\u044f!<\/p>\n<\/li>\n<\/ul>\n<figure class=\"full-width\">\n<div><figcaption>\u0410\u0440\u0442\u0435\u0444\u0430\u043a\u0442\u044b \u0432\u043e Flex<\/figcaption><\/div>\n<\/figure>\n<p>\u041f\u0440\u043e\u0431\u044b \u043e\u0441\u0442\u0430\u0432\u0448\u0438\u0445\u0441\u044f \u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a\u043e\u0432 \u0442\u043e\u0436\u0435 \u0431\u044b\u043b\u0438 \u043d\u0435\u0443\u0442\u0435\u0448\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u043c\u0438. InAppViewDebugger \u0442\u0430\u043a\u0436\u0435 \u0438\u043c\u0435\u043b \u043c\u043d\u043e\u0436\u0435\u0441\u0442\u0432\u043e \u0430\u0440\u0442\u0435\u0444\u0430\u043a\u0442\u043e\u0432 \u0438 \u043a\u0440\u0430\u0448\u0438\u043b\u0441\u044f, \u0430 Glance \u0445\u043e\u0442\u044c \u0438 \u043d\u0435 \u043f\u0430\u0434\u0430\u043b, \u043d\u043e \u043e\u0431\u0440\u0435\u0437\u0430\u043b \u0432\u044c\u044e\u0448\u043a\u0438 \u0438 \u0442\u0430\u043a\u0436\u0435 \u0438\u043c\u0435\u043b \u0430\u0440\u0442\u0435\u0444\u0430\u043a\u0442\u044b.<\/p>\n<figure class=\"full-width\">\n<div><figcaption>\u0410\u0440\u0442\u0435\u0444\u0430\u043a\u0442\u044b \u0432 InAppViewDebugger \u0438 Glance<\/figcaption><\/div>\n<\/figure>\n<figure class=\"float full-width\"><\/figure>\n<p>\u0418 \u0442\u0443\u0442 \u044f \u043f\u043e\u043d\u0438\u043c\u0430\u044e, \u0447\u0442\u043e \u044d\u0442\u043e \u0443\u0436\u0435 \u043d\u0435 \u043b\u0435\u0433\u043a\u0430\u044f \u043f\u0440\u043e\u0433\u0443\u043b\u043a\u0430 \u0438 \u0431\u044b\u0441\u0442\u0440\u043e \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u043d\u0438\u0447\u0435\u0433\u043e \u043d\u0435 \u0432\u044b\u0439\u0434\u0435\u0442. \u041f\u0440\u0438\u0434\u0435\u0442\u0441\u044f \u043f\u043e\u0432\u043e\u0437\u0438\u0442\u044c\u0441\u044f. <\/p>\n<h2>View \u0441\u043b\u043e\u0439<\/h2>\n<p>\u0420\u0435\u0448\u0438\u043b \u043f\u043e\u0439\u0442\u0438 \u043e\u0442 \u043f\u0440\u043e\u0441\u0442\u043e\u0433\u043e \u043a \u0441\u043b\u043e\u0436\u043d\u043e\u043c\u0443 \u0438 \u043d\u0430\u0447\u0430\u0442\u044c \u0440\u0430\u0431\u043e\u0442\u044b \u0441 \u0432\u044c\u044e \u0441\u043b\u043e\u044f \u2014 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438 \u043d\u0435 \u0438\u043c\u0435\u043b\u0438 \u043f\u0440\u043e\u0431\u043b\u0435\u043c \u0441 \u043d\u0438\u043c \u0438 \u0440\u0435\u0448\u0435\u043d\u0438\u0435 \u0442\u0443\u0442 \u043f\u043e\u0437\u0430\u0438\u043c\u0441\u0442\u0432\u043e\u0432\u0430\u043d\u043e. \u0414\u043b\u044f \u043d\u0435\u0433\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c SceneKit.<\/p>\n<p><a href=\"https:\/\/developer.apple.com\/documentation\/scenekit\/\">SceneKit<\/a> \u2014 \u044d\u0442\u043e \u0432\u044b\u0441\u043e\u043a\u043e\u0443\u0440\u043e\u0432\u043d\u0435\u0432\u044b\u0439 \u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a \u0434\u043b\u044f 3D-\u0433\u0440\u0430\u0444\u0438\u043a\u0438, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u043d\u0430\u043c \u0441\u043e\u0437\u0434\u0430\u0432\u0430\u0442\u044c 3D \u0441\u0446\u0435\u043d\u044b. \u0420\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u043f\u043e\u0432\u0435\u0440\u0445 Metal-\u0430 \u0438 \u0435\u0433\u043e \u043f\u0440\u0435\u0438\u043c\u0443\u0449\u0435\u0441\u0442\u0432\u0430 \u043f\u0435\u0440\u0435\u0434 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435\u043c \u0432 \u043f\u0435\u0440\u0432\u043e\u0437\u0434\u0430\u043d\u043d\u043e\u043c \u0432\u0438\u0434\u0435 \u0437\u0430\u043a\u043b\u044e\u0447\u0430\u0435\u0442\u0441\u044f \u0432 \u043f\u0440\u043e\u0441\u0442\u043e\u0442\u0435 \u2014 \u043d\u0435 \u043d\u0443\u0436\u043d\u043e \u043f\u043e\u0433\u0440\u0443\u0436\u0430\u0442\u044c\u0441\u044f \u043d\u0438 \u0432 \u043a\u0430\u043a\u0438\u0435 \u043d\u0438\u0437\u043a\u043e\u0443\u0440\u043e\u0432\u043d\u0435\u0432\u044b\u0435 API, \u0432\u0441\u0451 \u043f\u0440\u0435\u0434\u0435\u043b\u044c\u043d\u043e \u0443\u043f\u0440\u043e\u0449\u0435\u043d\u043e \u0438 \u043f\u043e\u043d\u044f\u0442\u043d\u043e.<\/p>\n<details class=\"spoiler\">\n<summary>\u041d\u0435\u0431\u043e\u043b\u044c\u0448\u0430\u044f \u0438\u0441\u0442\u043e\u0440\u0438\u0447\u0435\u0441\u043a\u0430\u044f \u0441\u043f\u0440\u0430\u0432\u043a\u0430:<\/summary>\n<div class=\"spoiler__content\">\n<ul>\n<li>\n<p>SceneKit \u0431\u044b\u043b \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d \u043d\u0430 macOS \u0432 2012.<\/p>\n<\/li>\n<li>\n<p>\u0412 2014 Apple \u043f\u043e\u0440\u0442\u0438\u0440\u043e\u0432\u0430\u043b\u0438 \u0435\u0433\u043e \u043d\u0430 iOS.<\/p>\n<\/li>\n<li>\n<p>\u041a \u043c\u043e\u043c\u0435\u043d\u0442\u0443 \u0430\u043d\u043e\u043d\u0441\u0430 ARKit-\u0430 \u0432 2017 \u0431\u044b\u043b \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u0440\u0430\u0437\u0432\u0438\u0442 \u0434\u043b\u044f \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f \u0438\u0445 \u0432 \u043f\u0430\u0440\u0435.<\/p>\n<\/li>\n<\/ul>\n<\/div>\n<\/details>\n<p>\u0418\u0442\u0430\u043a, \u043d\u0430\u0447\u043d\u0435\u043c \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0443 \u043d\u0430\u0448\u0435\u0439 \u0432\u044c\u044e.<\/p>\n<p><strong>\u041f\u0435\u0440\u0432\u043e\u0435, \u0447\u0442\u043e \u043d\u0430\u0434\u043e \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u2014 \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u044d\u043a\u0437\u0435\u043c\u043f\u043b\u044f\u0440\u044b SCNScene \u0438\u00a0SCNView.<\/strong><\/p>\n<pre><code class=\"swift\">private let sceneView = SCNView() private let scene = SCNScene() ... addSubview(sceneView) ... sceneView.allowsCameraControl = true sceneView.scene = scene<\/code><\/pre>\n<p>\u0412\u0441\u0451, \u0447\u0442\u043e \u043d\u0430\u0445\u043e\u0434\u0438\u0442\u0441\u044f \u0432 \u0432\u0438\u0440\u0442\u0443\u0430\u043b\u044c\u043d\u044b\u043c \u043f\u0440\u043e\u0441\u0442\u0440\u0430\u043d\u0441\u0442\u0432\u0435, \u043d\u0430\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u0441\u0446\u0435\u043d\u043e\u0439, \u0438 \u0437\u0430 \u043d\u0435\u0451 \u043e\u0442\u0432\u0435\u0447\u0430\u0435\u0442 \u043a\u043b\u0430\u0441\u0441 <a href=\"https:\/\/developer.apple.com\/documentation\/scenekit\/scnscene\">SCNScene<\/a>.<\/p>\n<figure class=\"full-width\"><\/figure>\n<p><a href=\"https:\/\/developer.apple.com\/documentation\/scenekit\/scnview\">SCNView<\/a> \u2014 \u044d\u0442\u043e \u0432\u044c\u044e\u0448\u043a\u0430, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u043c\u043e\u0436\u0435\u0442 \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u0441\u043e \u0441\u0446\u0435\u043d\u043e\u0439. \u0414\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c \u0435\u0451 \u0432 \u0438\u0435\u0440\u0430\u0440\u0445\u0438\u044e \u0438 \u0432\u043a\u043b\u044e\u0447\u0430\u0435\u043c \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440 <code>allowsCameraControl<\/code> \u2014 \u043e\u043d \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u043c\u0435\u043d\u044f\u0442\u044c \u043f\u043e\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u043a\u0430\u043c\u0435\u0440\u044b \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u0436\u0435\u0441\u0442\u043e\u0432 \u2014\u00a0\u0438 \u043f\u0440\u0438\u0441\u0432\u0430\u0438\u0432\u0430\u0435\u043c \u044d\u043a\u0437\u0435\u043c\u043f\u043b\u044f\u0440 \u0441\u0446\u0435\u043d\u044b \u0432\u043e \u0432\u044c\u044e.<\/p>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u043d\u0430\u0441\u0442\u0440\u043e\u0438\u043c \u043d\u043e\u0434\u0443 \u043a\u0430\u043c\u0435\u0440\u044b. <\/p>\n<figure class=\"full-width\"><\/figure>\n<p><a href=\"https:\/\/developer.apple.com\/documentation\/scenekit\/scnnode\">SCNNode<\/a> \u2014 \u044d\u0442\u043e \u043e\u0441\u043d\u043e\u0432\u043d\u043e\u0439 \u044d\u043b\u0435\u043c\u0435\u043d\u0442 \u0433\u0440\u0430\u0444\u0430 \u0441\u0446\u0435\u043d\u044b, \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u044f\u044e\u0449\u0438\u0439 \u043f\u043e\u0437\u0438\u0446\u0438\u044e \u0438 \u0442\u0440\u0430\u043d\u0441\u0444\u043e\u0440\u043c\u044b \u0432 \u0442\u0440\u0435\u0445\u043c\u0435\u0440\u043d\u043e\u043c \u043f\u0440\u043e\u0441\u0442\u0440\u0430\u043d\u0441\u0442\u0432\u0435, \u043a \u043a\u043e\u0442\u043e\u0440\u043e\u043c\u0443 \u043c\u043e\u0436\u043d\u043e \u043f\u0440\u0438\u043a\u0440\u0435\u043f\u0438\u0442\u044c \u0433\u0435\u043e\u043c\u0435\u0442\u0440\u0438\u044e, \u043e\u0441\u0432\u0435\u0449\u0435\u043d\u0438\u0435, \u043a\u0430\u043c\u0435\u0440\u044b \u0438\u043b\u0438 \u0434\u0440\u0443\u0433\u043e\u0439 \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0430\u0435\u043c\u044b\u0439 \u043a\u043e\u043d\u0442\u0435\u043d\u0442.<\/p>\n<pre><code class=\"swift\">private let cameraNode = SCNNode() cameraNode.camera = SCNCamera() scene.rootNode.addChildNode(cameraNode)<\/code><\/pre>\n<p><a href=\"https:\/\/developer.apple.com\/documentation\/scenekit\/scncamera\">SCNCamera<\/a> \u2014 \u043d\u0430\u0431\u043e\u0440 \u0430\u0442\u0440\u0438\u0431\u0443\u0442\u043e\u0432 \u043a\u0430\u043c\u0435\u0440\u044b, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043c\u043e\u0436\u043d\u043e \u043f\u0440\u0438\u043a\u0440\u0435\u043f\u0438\u0442\u044c \u043a <code>SCNNode<\/code>, \u0447\u0442\u043e\u0431\u044b \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0438\u0442\u044c \u0442\u043e\u0447\u043a\u0443, \u0441 \u043a\u043e\u0442\u043e\u0440\u043e\u0439 \u043c\u044b \u0431\u0443\u0434\u0435\u043c \u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c \u043d\u0430 \u043a\u043e\u043d\u0442\u0435\u043d\u0442. \u0412 \u0434\u0430\u043b\u044c\u043d\u0435\u0439\u0448\u0435\u043c \u043c\u044b \u043f\u0440\u0438\u0441\u0432\u0430\u0438\u0432\u0430\u0435\u043c\u00a0\u0432 \u043d\u0435\u0451 \u043f\u043e\u0437\u0438\u0446\u0438\u044e, \u0447\u0442\u043e \u0440\u0430\u0441\u0441\u0447\u0438\u0442\u044b\u0432\u0430\u0435\u043c \u0438\u0441\u0445\u043e\u0434\u044f \u0438\u0437 \u0432\u044c\u044e \u043c\u043e\u0434\u0435\u043b\u0435\u0439 \u0438 \u0438\u0445 \u043c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u044c\u043d\u043e\u0439 \u0433\u043b\u0443\u0431\u0438\u043d\u044b.<\/p>\n<p>\u041f\u0435\u0440\u0435\u0439\u0434\u0435\u043c \u043a ViewModel \u0438 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0438\u043c\u0441\u044f \u0441 \u0442\u0435\u043c, \u0447\u0442\u043e \u043d\u0430\u043c \u0432 \u043d\u0435\u0439 \u043d\u0443\u0436\u043d\u043e. \u041f\u043e\u0434 \u0432\u044c\u044e-\u043c\u043e\u0434\u0435\u043b\u044c\u044e \u044f \u043f\u043e\u0434\u0440\u0430\u0437\u0443\u043c\u0435\u0432\u0430\u044e \u0434\u0430\u043d\u043d\u044b\u0435 \u0434\u043b\u044f \u043f\u043e\u043a\u0430\u0437\u0430 \u0432\u044c\u044e, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043d\u0435 \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0442 \u043a\u0430\u043a\u043e\u0439-\u043b\u0438\u0431\u043e \u0431\u0438\u0437\u043d\u0435\u0441-\u043b\u043e\u0433\u0438\u043a\u0438. \u041d\u0430\u043c \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c \u043c\u0430\u0441\u0441\u0438\u0432 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u043e\u0432, \u0434\u043b\u044f \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u0438\u0437 \u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u0431\u0443\u0434\u0435\u043c \u0441\u043e\u0437\u0434\u0430\u0432\u0430\u0442\u044c \u043d\u043e\u0434\u0443, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0431\u0443\u0434\u0435\u0442 \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0442\u044c\u0441\u044f \u0432 \u0441\u0446\u0435\u043d\u0443. \u0418 \u0434\u043b\u044f \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u0442\u0430\u043a\u043e\u0433\u043e \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u0430 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u044b:<\/p>\n<ul>\n<li>\n<p>\u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0435 \u0432\u044c\u044e \u2014 \u0441\u043d\u0430\u043f\u0448\u043e\u0442;<\/p>\n<\/li>\n<li>\n<p>\u0433\u043b\u0443\u0431\u0438\u043d\u0430 \u2014 \u043f\u043e\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u0432\u044c\u044e \u043f\u043e z-\u043e\u0441\u0438;<\/p>\n<\/li>\n<li>\n<p>\u0440\u0430\u0437\u043c\u0435\u0440 \u0438 \u043f\u043e\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u2014 \u0434\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c \u0444\u0440\u0435\u0439\u043c;<\/p>\n<\/li>\n<li>\n<p>\u0441\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u0438\u0441\u0445\u043e\u0434\u043d\u0443\u044e \u0432\u044c\u044e \u0434\u043b\u044f \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0445 \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0439 (\u043e\u0442\u043a\u0440\u044b\u0442\u0438\u0435 \u0434\u0435\u0442\u0430\u043b\u0435\u0439).<\/p>\n<\/li>\n<\/ul>\n<p>\u0418\u0442\u043e\u0433\u043e, \u0432\u044c\u044e-\u043c\u043e\u0434\u0435\u043b\u044c \u0431\u0443\u0434\u0435\u0442 \u0432\u044b\u0433\u043b\u044f\u0434\u0435\u0442\u044c \u0442\u0430\u043a:\u00a0<\/p>\n<pre><code class=\"swift\">enum VisualDebugger {     enum PresentModuleData {         struct ViewModel: Equatable {             let layoutModels: [LayoutModel]         }     }      struct LayoutModel: Equatable {         let image: UIImage         let depth: Float         let frame: CGRect         let view: UIView     } }<\/code><\/pre>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c, \u043f\u0440\u0438 \u043f\u0440\u0438\u0441\u0432\u0430\u0438\u0432\u0430\u043d\u0438\u0438 \u0432\u044c\u044e-\u043c\u043e\u0434\u0435\u043b\u0438 \u0432\u043e \u0432\u044c\u044e \u043d\u0430\u0448\u0435\u0433\u043e VisualDebugger-\u0430, \u0434\u043b\u044f \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u043e\u0431\u044a\u0435\u043a\u0442\u0430 \u0438\u0437 \u043c\u0430\u0441\u0441\u0438\u0432\u0430 \u043c\u044b \u0431\u0443\u0434\u0435\u043c \u0441\u043e\u0437\u0434\u0430\u0432\u0430\u0442\u044c \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u0443\u044e \u043d\u043e\u0434\u0443, \u043a\u043e\u0442\u043e\u0440\u0443\u044e \u0431\u0443\u0434\u0435\u043c \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0442\u044c \u043a\u0430\u043a childNode \u0432 \u0441\u0446\u0435\u043d\u0443.<\/p>\n<p>\u0414\u0435\u043b\u0430\u0442\u044c \u043c\u044b \u0431\u0443\u0434\u0435\u043c \u044d\u0442\u043e c \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0439 \u0444\u0443\u043d\u043a\u0446\u0438\u0438:<\/p>\n<pre><code class=\"swift\">func addChildNode(for model: VisualDebugger.LayoutModel) {     let geometry = SCNPlane(         width: model.frame.size.width \/ \u0441oefficient,         height: model.frame.size.height \/ \u0441oefficient     )     let material = SCNMaterial()     material.isDoubleSided = true     material.diffuse.contents = model.image     geometry.materials = [material]     let geometryNode = SCNNode(geometry: geometry)     geometryNode.position = calculatePosition(        for: model,        spacing: appearance.defaultZSpacing     )     geometryNode.accessibilityLabel = makeID(for: model.view)     childNodes.append(geometryNode)     scene.rootNode.addChildNode(geometryNode) }<\/code><\/pre>\n<p>\u041f\u0435\u0440\u0432\u044b\u043c \u0434\u0435\u043b\u043e\u043c \u0441\u043e\u0437\u0434\u0430\u0435\u043c \u0433\u0435\u043e\u043c\u0435\u0442\u0440\u0438\u044e \u2014 \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u0435 3D-\u0444\u0438\u0433\u0443\u0440\u044b \u043d\u043e\u0434\u0430. \u041c\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c <a href=\"https:\/\/developer.apple.com\/documentation\/scenekit\/scnplane\">SCNPlane<\/a> \u2014 \u044d\u0442\u043e \u043f\u0440\u044f\u043c\u043e\u0443\u0433\u043e\u043b\u044c\u043d\u0438\u043a, \u043a\u043e\u0442\u043e\u0440\u043e\u043c\u0443 \u043c\u044b \u0437\u0430\u0434\u0430\u0435\u043c \u0448\u0438\u0440\u0438\u043d\u0443 \u0438 \u0432\u044b\u0441\u043e\u0442\u0443. \u0422\u0430\u043a\u0436\u0435 SceneKit \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u0441\u043e\u0437\u0434\u0430\u0432\u0430\u0442\u044c \u043f\u0440\u043e\u0441\u0442\u044b\u0435 \u043e\u0431\u044a\u0435\u043c\u043d\u044b\u0435 \u0444\u0438\u0433\u0443\u0440\u044b \u0442\u0438\u043f\u0430 \u0448\u0430\u0440\u0430, \u043a\u0443\u0431\u0430, \u0446\u0438\u043b\u0438\u043d\u0434\u0440\u0430 \u0438 \u0438\u043c\u043f\u043e\u0440\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0441\u043b\u043e\u0436\u043d\u044b\u0435 3D-\u043c\u043e\u0434\u0435\u043b\u0438 \u0438\u0437 \u0432\u043d\u0435\u0448\u043d\u0438\u0445 \u0440\u0435\u0434\u0430\u043a\u0442\u043e\u0440\u043e\u0432.<\/p>\n<figure class=\"full-width\"><\/figure>\n<p>\u041e\u0431\u044a\u0435\u043a\u0442 \u0435\u0441\u0442\u044c. \u0410 \u0438\u0437 \u043a\u0430\u043a\u043e\u0433\u043e \u043e\u043d \u043c\u0430\u0442\u0435\u0440\u0438\u0430\u043b\u0430? \u0414\u043b\u044f \u043f\u0440\u0438\u0441\u0432\u043e\u0435\u043d\u0438\u044f \u043c\u0430\u0442\u0435\u0440\u0438\u0430\u043b\u0430 \u0434\u043b\u044f \u043d\u0430\u0448\u0435\u0439 \u0433\u0435\u043e\u043c\u0435\u0442\u0440\u0438\u0438 \u0431\u0435\u0440\u0451\u043c <a href=\"https:\/\/developer.apple.com\/documentation\/scenekit\/scnmaterial\">SCNMaterial<\/a> \u2014 \u043d\u0430\u0431\u043e\u0440 \u0441\u0432\u043e\u0439\u0441\u0442\u0432, \u043e\u043f\u0438\u0441\u044b\u0432\u0430\u044e\u0449\u0438\u0445 \u0442\u043e, \u043a\u0430\u043a \u0431\u0443\u0434\u0435\u0442 \u0432\u044b\u0433\u043b\u044f\u0434\u0435\u0442\u044c \u043d\u0430\u0448\u0430 \u0433\u0435\u043e\u043c\u0435\u0442\u0440\u0438\u044f \u043f\u043e\u0441\u043b\u0435 \u0440\u0435\u043d\u0434\u0435\u0440\u0438\u043d\u0433\u0430.<\/p>\n<p>Difuse \u2014 \u044d\u0442\u043e \u043e\u0431\u044a\u0435\u043a\u0442, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0435\u0442 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0441\u0432\u0435\u0442\u0430, \u0434\u0438\u0444\u0444\u0443\u0437\u043d\u043e \u043e\u0442\u0440\u0430\u0436\u0435\u043d\u043d\u043e\u0433\u043e \u043e\u0442 \u043f\u043e\u0432\u0435\u0440\u0445\u043d\u043e\u0441\u0442\u0438. \u0412 \u043d\u0435\u0433\u043e \u043c\u044b \u043f\u0440\u0438\u0441\u0432\u0430\u0438\u0432\u0430\u0435\u043c \u043a\u043e\u043d\u0442\u0435\u043d\u0442 \u2014 \u044d\u0442\u043e \u043d\u0430\u0448\u0435 \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0435.<\/p>\n<p>\u0422\u0430\u043a\u0436\u0435 SceneKit \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u043d\u0430\u0441\u0442\u0440\u043e\u0438\u0442\u044c metalness \u0438 roughness \u2014 \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u0430, \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u044e\u0449\u0438\u0435 \u0442\u043e, \u043d\u0430\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u043c\u0430\u0442\u0435\u0440\u0438\u0430\u043b \u0431\u0443\u0434\u0435\u0442 \u043f\u043e\u0445\u043e\u0436 \u043d\u0430 \u043c\u0435\u0442\u0430\u043b\u043b \u0438 \u0442\u043e, \u043d\u0430\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0443 \u043d\u0435\u0433\u043e \u0431\u0443\u0434\u0435\u0442 \u043d\u0430\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0440\u043e\u0432\u043d\u0430\u044f \u043f\u043e\u0432\u0435\u0440\u0445\u043d\u043e\u0441\u0442\u044c, \u043d\u043e \u0432 \u0440\u0430\u043c\u043a\u0430\u0445 \u043d\u0430\u0448\u0435\u0439 \u0444\u0438\u0447\u0438 \u043c\u044b \u043d\u0435 \u0431\u0443\u0434\u0435\u043c \u044d\u0442\u043e\u0433\u043e \u0434\u0435\u043b\u0430\u0442\u044c \u2014 \u043d\u0435 \u043e\u0441\u043e\u0431\u043e \u0438 \u043d\u0443\u0436\u043d\u043e \ud83d\ude42<\/p>\n<figure class=\"full-width\"><\/figure>\n<p>\u0414\u0430\u043b\u0435\u0435 \u0441\u043e\u0437\u0434\u0430\u0434\u0438\u043c \u043d\u043e\u0434\u0443 \u043d\u0430 \u0431\u0430\u0437\u0435 \u0433\u0435\u043e\u043c\u0435\u0442\u0440\u0438\u0438 \u0438 \u0440\u0430\u0441\u0441\u0447\u0438\u0442\u0430\u0435\u043c \u0434\u043b\u044f \u043d\u0435\u0451 \u043f\u043e\u0437\u0438\u0446\u0438\u044e \u043d\u0430 \u0431\u0430\u0437\u0435 \u0444\u0440\u0435\u0439\u043c\u0430 \u0432\u044c\u044e\u0448\u043a\u0438. \u041f\u0440\u0438 \u0440\u0430\u0441\u0447\u0435\u0442\u0435 \u043f\u043e\u0437\u0438\u0446\u0438\u0438 \u043d\u043e\u0434\u044b \u0441\u0442\u043e\u0438\u0442 \u0443\u0447\u0438\u0442\u044b\u0432\u0430\u0442\u044c, \u0447\u0442\u043e \u043e\u0441\u044c \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442 \u0432 SceneKit \u043e\u0442\u043b\u0438\u0447\u0430\u0435\u0442\u0441\u044f \u043e\u0442 \u0442\u043e\u0439, \u043a\u043e\u0442\u043e\u0440\u0443\u044e \u043c\u044b \u043f\u0440\u0438\u0432\u044b\u043a\u043b\u0438 \u0432\u0438\u0434\u0435\u0442\u044c \u0432 UIKit \u2014 \u043e\u0441\u044c Y \u0438\u043d\u0432\u0435\u0440\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0430, \u0430 \u043f\u043e\u0437\u0438\u0446\u0438\u044f \u043d\u0430\u0448\u0435\u0439 \u0433\u0435\u043e\u043c\u0435\u0442\u0440\u0438\u0438 \u0441\u0447\u0438\u0442\u0430\u0435\u0442\u0441\u044f \u043e\u0442 \u0435\u0451 \u0441\u0435\u0440\u0435\u0434\u0438\u043d\u044b. <\/p>\n<figure class=\"full-width\"><\/figure>\n<p>\u0418 \u043f\u0435\u0440\u0435\u0433\u043e\u043d\u044f\u0442\u044c \u0444\u0440\u0435\u0439\u043c \u0432 \u043f\u043e\u0437\u0438\u0446\u0438\u044e \u043d\u043e\u0434\u044b (<a href=\"https:\/\/developer.apple.com\/documentation\/scenekit\/scnvector3\">SCNVector3<\/a>) \u043c\u044b \u0431\u0443\u0434\u0435\u043c \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0439 \u0444\u0443\u043d\u043a\u0446\u0438\u0438:<\/p>\n<pre><code class=\"swift\">func calculatePosition(     for model: VisualDebugger.LayoutModel,      spacing: Float ) -> SCNVector3 {     SCNVector3(         x: Float(model.frame.midX \/ \u0441oefficient),         y: Float(model.frame.midY.negative \/ \u0441oefficient),         z: model.depth * spacing      ) }<\/code><\/pre>\n<p>\u0417\u0434\u0435\u0441\u044c \u0436\u0435 \u043f\u0440\u0438\u0441\u0432\u043e\u0438\u043c <code>accessabilityLabel<\/code> \u0434\u043b\u044f \u043d\u043e\u0434\u044b, \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u044b\u0439 \u0434\u043b\u044f \u043f\u043e\u0438\u0441\u043a\u0430 \u0430\u0441\u0441\u043e\u0446\u0438\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u043e\u0439 \u0432\u044c\u044e \u043c\u043e\u0434\u0435\u043b\u0438 \u043f\u0440\u0438 \u0442\u0430\u043f\u0435. \u0410 \u0442\u0430\u043f\u044b \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u044b\u0432\u0430\u0435\u043c \u043f\u0440\u043e\u0441\u0442\u044b\u043c \u043d\u0430\u0432\u0435\u0448\u0438\u0432\u0430\u043d\u0438\u0435\u043c  <code>gestureRecognizer<\/code> \u043d\u0430 <code>sceneView<\/code> \u0438 \u0432\u044b\u0437\u043e\u0432\u043e\u043c <code>hitTest<\/code> \u0434\u043b\u044f <code>sceneView<\/code>, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0431\u0443\u0434\u0435\u0442 \u0432\u044b\u0434\u0430\u0432\u0430\u0442\u044c \u043d\u0443\u0436\u043d\u0443\u044e \u043d\u043e\u0434\u0443.<\/p>\n<p>\u041f\u043b\u044e\u0441, \u0431\u044b\u043b\u0438 \u043d\u0430\u0441\u0442\u0440\u043e\u0435\u043d\u044b \u0441\u043b\u0430\u0439\u0434\u0435\u0440\u044b \u0440\u0430\u0441\u0441\u0442\u043e\u044f\u043d\u0438\u044f \u043c\u0435\u0436\u0434\u0443 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u0430\u043c\u0438 \u0438 \u0433\u043b\u0443\u0431\u0438\u043d\u044b \u043f\u0440\u043e\u0440\u0438\u0441\u043e\u0432\u043a\u0438. \u041e\u043d\u0438 \u0441\u043a\u0440\u044b\u0432\u0430\u044e\u0442 \u043d\u043e\u0434\u0443, \u0435\u0441\u043b\u0438 \u0433\u043b\u0443\u0431\u0438\u043d\u0430 \u0431\u043e\u043b\u044c\u0448\u0435 \u0443\u043a\u0430\u0437\u0430\u043d\u043d\u043e\u0439 \u0438\u043b\u0438 \u0438\u0437\u043c\u0435\u043d\u044f\u044e\u0442 \u043f\u043e\u0437\u0438\u0446\u0438\u044e \u043d\u043e\u0434, \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0435\u043d\u043d\u043e.<\/p>\n<p>\u041d\u0430\u043f\u0438\u0441\u0430\u0432 \u0441\u043e\u0432\u0441\u0435\u043c \u043d\u0435\u043c\u043d\u043e\u0433\u043e \u043a\u043e\u0434\u0430 \u0434\u043b\u044f \u0432\u044c\u044e \u0441\u043b\u043e\u044f \u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044f \u043f\u043e\u0434\u0433\u043e\u0442\u043e\u0432\u043a\u0443 \u0434\u0430\u043d\u043d\u044b\u0445 \u0434\u043b\u044f \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044f \u0438\u0437 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438 Glance, \u043f\u043e\u043b\u0443\u0447\u0438\u043b\u0441\u044f \u0443\u0436\u0435 \u0432\u043f\u043e\u043b\u043d\u0435 \u0440\u0430\u0431\u043e\u0447\u0438\u0439 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442. <\/p>\n<div class=\"tm-iframe_temp\" data-src=\"https:\/\/embedd.srv.habr.com\/iframe\/655cbcdb6f566b30a58e3471\" data-style=\"\" id=\"655cbcdb6f566b30a58e3471\" width=\"\"><\/div>\n<p>\u041a\u0430\u043a \u0432\u044b \u043c\u043e\u0433\u043b\u0438 \u0443\u0432\u0438\u0434\u0435\u0442\u044c, SceneKit \u0438\u043d\u0442\u0443\u0438\u0442\u0438\u0432\u043d\u043e \u043f\u043e\u043d\u044f\u0442\u0435\u043d, \u0434\u043e\u0432\u043e\u043b\u044c\u043d\u043e \u043f\u0440\u043e\u0441\u0442 \u0438 \u0431\u044b\u0441\u0442\u0440 \u0432 \u043e\u0441\u0432\u043e\u0435\u043d\u0438\u0438. \u0417\u0430 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0447\u0430\u0441\u043e\u0432 \u044f \u043f\u043e\u043b\u0443\u0447\u0438\u043b \u0433\u043e\u0442\u043e\u0432\u0443\u044e \u0432\u044c\u044e\u0448\u043a\u0443, \u0432\u0437\u0433\u043b\u044f\u043d\u0443\u0432 \u043d\u0430 \u043a\u043e\u0442\u043e\u0440\u0443\u044e, \u043c\u043e\u0436\u043d\u043e \u043f\u043e\u0447\u0443\u0432\u0441\u0442\u0432\u043e\u0432\u0430\u0442\u044c \u0432\u0430\u0443-\u044d\u0444\u0444\u0435\u043a\u0442, \u0445\u043e\u0442\u044c \u0438 \u0441\u0438\u043b \u0442\u0443\u0434\u0430 \u043e\u0441\u043e\u0431\u043e \u043d\u0435 \u0432\u043a\u043b\u0430\u0434\u044b\u0432\u0430\u043b\u043e\u0441\u044c.<\/p>\n<p>\u041f\u0435\u0440\u0435\u0439\u0434\u0435\u043c \u043a \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0439 \u0447\u0430\u0441\u0442\u0438 \u2014 \u043f\u043e\u0434\u0433\u043e\u0442\u043e\u0432\u0438\u043c \u0434\u0430\u043d\u043d\u044b\u0435 \u0434\u043b\u044f \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044f.<\/p>\n<h2>\u0413\u043e\u0442\u043e\u0432\u0438\u043c \u0434\u0430\u043d\u043d\u044b\u0435 \u0434\u043b\u044f \u043f\u043e\u043a\u0430\u0437\u0430<\/h2>\n<p><strong>\u0414\u0438\u0441\u043a\u043b\u0435\u0439\u043c\u0435\u0440!<\/strong> \u041d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0444\u0440\u0430\u0433\u043c\u0435\u043d\u0442\u044b \u043a\u043e\u0434\u0430 \u043c\u043e\u0433\u0443\u0442 \u0432\u0430\u0441 \u0448\u043e\u043a\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0438 \u043c\u043e\u0436\u0435\u0442 \u043f\u043e\u044f\u0432\u0438\u0442\u044c\u0441\u044f \u043d\u0435\u043f\u0440\u0435\u043e\u0434\u043e\u043b\u0438\u043c\u043e\u0435 \u0436\u0435\u043b\u0430\u043d\u0438\u0435 \u0447\u0442\u043e-\u0442\u043e \u043e\u0442\u0440\u0435\u0444\u0430\u043a\u0442\u043e\u0440\u0438\u0442\u044c \u0438\u043b\u0438 \u0441\u043a\u0430\u0437\u0430\u0442\u044c \u2014 \u043d\u0435 \u043f\u043e <a href=\"https:\/\/github.com\/alfa-laboratory\/YARCH\">\u044f\u0440\u043a\u0443<\/a>. \u041f\u0440\u043e\u0448\u0443 \u043e\u0442\u043d\u0435\u0441\u0442\u0438\u0441\u044c \u0441 \u043f\u043e\u043d\u0438\u043c\u0430\u043d\u0438\u0435\u043c \u0438 \u043f\u043e\u043c\u043d\u0438\u0442\u044c, \u0447\u0442\u043e \u043d\u0430 \u0437\u0430\u0434\u0430\u0447\u0443 \u0438\u0437\u043d\u0430\u0447\u0430\u043b\u044c\u043d\u043e \u043e\u0442\u0432\u043e\u0434\u0438\u043b\u043e\u0441\u044c \u0442\u043e\u043b\u044c\u043a\u043e 4 \u0434\u043d\u044f. <\/p>\n<p>\u041d\u0430\u0447\u043d\u0443 \u0441 \u0442\u043e\u0433\u043e, \u0447\u0442\u043e \u043e\u0441\u043d\u043e\u0432\u043d\u044b\u0435 \u0441\u043b\u043e\u0436\u043d\u043e\u0441\u0442\u0438 \u0441 \u0437\u0430\u0434\u0430\u0447\u0435\u0439 \u044f \u0432\u0441\u0442\u0440\u0435\u0442\u0438\u043b \u0438\u043c\u0435\u043d\u043d\u043e \u043d\u0430 \u044d\u0442\u043e\u043c \u044d\u0442\u0430\u043f\u0435. \u0411\u044b\u043b\u043e \u0434\u043e\u0432\u043e\u043b\u044c\u043d\u043e \u0441\u043b\u043e\u0436\u043d\u043e \u0441\u0440\u0430\u0437\u0443 \u0441\u0444\u043e\u0440\u043c\u0443\u043b\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0434\u043b\u044f \u0441\u0435\u0431\u044f \u0432\u0441\u0435 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u044b \u0442\u043e\u0433\u043e, \u0447\u0442\u043e \u0438\u043c\u0435\u043d\u043d\u043e \u0441\u0447\u0438\u0442\u0430\u0442\u044c \u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u044b\u043c \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0435\u043c. \u041d\u043e \u0432\u0441\u0451-\u0442\u0430\u043a\u0438 \u044f \u0432\u044b\u0432\u0435\u043b \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043a\u0440\u0438\u0442\u0435\u0440\u0438\u0438 \u0440\u0430\u0431\u043e\u0442\u044b, \u043e\u0442\u0442\u0430\u043b\u043a\u0438\u0432\u0430\u044f\u0441\u044c \u043e\u0442 \u0442\u043e\u0433\u043e, \u0447\u0442\u043e \u0431\u044b\u043b\u043e \u043d\u0435 \u0442\u0430\u043a \u0432 \u0433\u043e\u0442\u043e\u0432\u044b\u0445 \u0440\u0435\u0448\u0435\u043d\u0438\u044f\u0445:<\/p>\n<ul>\n<li>\n<p>\u0422\u0435 \u0432\u044c\u044e, \u0447\u0442\u043e \u043c\u044b \u043d\u0435 \u0432\u0438\u0434\u0438\u043c, \u043d\u0435 \u0434\u043e\u043b\u0436\u043d\u044b \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0430\u0442\u044c\u0441\u044f \u0438 \u043d\u0430\u043e\u0431\u043e\u0440\u043e\u0442. \u042d\u0442\u043e \u0437\u043d\u0430\u0447\u0438\u0442, \u0447\u0442\u043e \u0432\u044c\u044e \u043d\u0435 \u0434\u043e\u043b\u0436\u043d\u0430 \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0430\u0435\u0442\u0441\u044f \u0435\u0441\u043b\u0438 <code>isHidden == true<\/code>, <code>alpha == 0<\/code> \u0438 \u0432\u044c\u044e \u043d\u0435 \u0432\u043b\u0435\u0437\u0430\u0435\u0442 \u0432 \u043e\u0431\u043b\u0430\u0441\u0442\u044c \u0432\u0438\u0434\u0438\u043c\u043e\u0441\u0442\u0438 \u0440\u0443\u0442\u043e\u0432\u043e\u0439 \u0432\u044c\u044e (\u044d\u0442\u043e \u0442\u0430 \u0432\u044c\u044e, \u0434\u043b\u044f \u043a\u043e\u0442\u043e\u0440\u043e\u0439 \u043c\u044b \u0441\u0442\u0440\u043e\u0438\u043c \u0433\u0440\u0430\u0444). <\/p>\n<\/li>\n<li>\n<p>\u0415\u0441\u043b\u0438 \u0441\u0430\u043c\u0430 \u0432\u044c\u044e \u043d\u0435 \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0430\u0435\u0442\u0441\u044f, \u043d\u043e \u0443 \u043d\u0435\u0435 \u0435\u0441\u0442\u044c \u0441\u0430\u0431\u0432\u044c\u044e, \u0432\u044b\u0445\u043e\u0434\u044f\u0449\u0430\u044f \u0437\u0430 \u0435\u0435 \u0431\u0430\u0443\u043d\u0434\u0441, \u0438 \u043f\u0440\u0438 \u044d\u0442\u043e\u043c \u0443 \u043d\u0435\u0451<code>clipsToBounds == false<\/code>, \u0442\u043e \u0441\u0430\u0431\u0432\u044c\u044e \u043c\u044b \u0443\u0436\u0435 \u0434\u043e\u043b\u0436\u043d\u044b \u043e\u0442\u0440\u0438\u0441\u043e\u0432\u0430\u0442\u044c.<\/p>\n<\/li>\n<li>\n<p>\u0422\u0435 \u0447\u0430\u0441\u0442\u0438 \u0432\u044c\u044e, \u0447\u0442\u043e \u043c\u044b \u043d\u0435 \u0432\u0438\u0434\u0438\u043c, \u0434\u043e\u043b\u0436\u043d\u044b \u043e\u0431\u0440\u0435\u0437\u0430\u0442\u044c\u0441\u044f.<\/p>\n<\/li>\n<li>\n<p>\u0414\u043e\u043b\u0436\u043d\u0430 \u0432\u044b\u0441\u0442\u0430\u0432\u043b\u044f\u0442\u044c\u0441\u044f \u043a\u043e\u0440\u0440\u0435\u043a\u0442\u043d\u0430\u044f \u00ab\u0433\u043b\u0443\u0431\u0438\u043d\u0430\u00bb. \u0423\u0447\u0438\u0442\u044b\u0432\u0430\u0435\u043c, \u0447\u0442\u043e \u0434\u043b\u044f \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u0438\u0445 \u0432\u044c\u044e \u043e\u0434\u043d\u043e\u0433\u043e \u0440\u043e\u0434\u0438\u0442\u0435\u043b\u044f, \u0435\u0441\u043b\u0438 \u0438\u0445 \u0444\u0440\u0435\u0439\u043c\u044b \u043d\u0435 \u043f\u0435\u0440\u0435\u0441\u0435\u043a\u0430\u044e\u0442\u0441\u044f, \u0433\u043b\u0443\u0431\u0438\u043d\u0430 \u0434\u043e\u043b\u0436\u043d\u0430 \u0431\u044b\u0442\u044c \u043e\u0434\u0438\u043d\u0430\u043a\u043e\u0432\u0430.<\/p>\n<\/li>\n<\/ul>\n<h3>\u041f\u0440\u043e\u0432\u0430\u0439\u0434\u0435\u0440 \u0434\u0430\u043d\u043d\u044b\u0445<\/h3>\n<p>\u0417\u0434\u0435\u0441\u044c \u0432\u0441\u0451 \u0437\u0430\u0432\u044f\u0437\u0430\u043d\u043e \u043d\u0430 \u0444\u0443\u043d\u043a\u0446\u0438\u044e, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0440\u0435\u043a\u0443\u0440\u0441\u0438\u0432\u043d\u043e \u043f\u0440\u043e\u0445\u043e\u0434\u0438\u0442 \u043f\u043e \u0432\u0441\u0435\u043c \u0441\u0430\u0431\u0432\u044c\u044e, \u0440\u0430\u0441\u0441\u0447\u0438\u0442\u044b\u0432\u0430\u0435\u0442 \u0438\u0445 \u0433\u043b\u0443\u0431\u0438\u043d\u0443 \u0438 \u043e\u0442\u0434\u0430\u0435\u0442 \u0440\u0430\u0431\u043e\u0442\u0443 \u043d\u0430 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u043c\u043e\u0434\u0435\u043b\u0438 \u0431\u0438\u043b\u0434\u0435\u0440\u0443.<\/p>\n<pre><code class=\"swift\">func getViewHierarchy() ->[VisualDebugger.LayoutModel] {     var depth: Float = 0     return getLayoutModelsRecursively(for: rootView,<\/code><\/pre>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\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-360699","post","type-post","status-publish","format-standard","hentry"],"_links":{"self":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/360699","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=360699"}],"version-history":[{"count":0,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/360699\/revisions"}],"wp:attachment":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=360699"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=360699"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=360699"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}