{"id":284254,"date":"2017-03-31T17:15:02","date_gmt":"2017-03-31T13:15:02","guid":{"rendered":"http:\/\/savepearlharbor.com\/?p=284254"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-29T21:00:00","slug":"","status":"publish","type":"post","link":"https:\/\/savepearlharbor.com\/?p=284254","title":{"rendered":"\u0413\u0430\u0439\u0434 \u043f\u043e \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044e \u043f\u0440\u043e\u0441\u0442\u043e\u0433\u043e \u0444\u043e\u0442\u043e\u0440\u0435\u0434\u0430\u043a\u0442\u043e\u0440\u0430"},"content":{"rendered":"<p>\u0421\u0435\u0433\u043e\u0434\u043d\u044f \u043c\u044b \u043f\u0440\u0435\u0434\u043b\u0430\u0433\u0430\u0435\u043c \u0447\u0438\u0442\u0430\u0442\u0435\u043b\u044f\u043c \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u043e\u0435 \u0440\u0443\u043a\u043e\u0432\u043e\u0434\u0441\u0442\u0432\u043e \u043f\u043e \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044e \u043f\u0440\u043e\u0441\u0442\u043e\u0433\u043e \u0444\u043e\u0442\u043e\u0440\u0435\u0434\u0430\u043a\u0442\u043e\u0440\u0430 \u043d\u0430 iOS. \u0414\u043b\u044f \u043e\u043f\u044b\u0442\u043d\u044b\u0445 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u043e\u0432 \u0437\u0430\u0434\u0430\u0447\u0430 \u043d\u0435\u0441\u043b\u043e\u0436\u043d\u0430\u044f, \u043d\u043e \u043d\u043e\u0432\u0438\u0447\u043a\u0430\u043c \u043f\u043e\u0434\u043e\u0431\u043d\u044b\u0439 \u043f\u043e\u0448\u0430\u0433\u043e\u0432\u044b\u0439 \u0440\u0430\u0437\u0431\u043e\u0440 \u0432\u0441\u0435\u0433\u043e \u043f\u0440\u043e\u0446\u0435\u0441\u0441\u0430, \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e, \u043e\u043a\u0430\u0436\u0435\u0442\u0441\u044f \u043f\u043e\u043b\u0435\u0437\u0435\u043d. \u041c\u044b \u043e\u0442\u0434\u0430\u043b\u0438 \u043f\u0440\u0435\u0434\u043f\u043e\u0447\u0442\u0435\u043d\u0438\u0435 \u043a\u043b\u0430\u0441\u0441\u0438\u0447\u0435\u0441\u043a\u043e\u0439 \u0441\u0440\u0435\u0434\u0435 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u0434\u043b\u044f \u0432\u044b\u0431\u0440\u0430\u043d\u043d\u043e\u0439 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u043e\u043d\u043d\u043e\u0439 \u0441\u0438\u0441\u0442\u0435\u043c\u044b \u2013 Xcode version 8.2.1. \u0420\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0443 \u0431\u0443\u0434\u0435\u043c \u0432\u0435\u0441\u0442\u0438, \u043e\u043f\u044f\u0442\u044c \u0436\u0435, \u043d\u0430 \u043a\u043b\u0430\u0441\u0441\u0438\u0447\u0435\u0441\u043a\u043e\u043c \u043e\u0431\u044a\u0435\u043a\u0442\u043d\u043e-\u043e\u0440\u0438\u0435\u043d\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u043e\u043c \u044f\u0437\u044b\u043a\u0435 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f Objective-C.<\/p>\n<p>  \u041f\u0440\u0435\u0436\u0434\u0435 \u0447\u0435\u043c \u043f\u0440\u0438\u0441\u0442\u0443\u043f\u0430\u0442\u044c \u043a \u0441\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u043e \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0435, \u043f\u0440\u0435\u0434\u043b\u0430\u0433\u0430\u0435\u043c \u0441\u043d\u0430\u0447\u0430\u043b\u0430 \u0440\u0430\u0437\u0431\u0438\u0442\u044c \u0437\u0430\u0434\u0430\u0447\u0443 \u043d\u0430 \u043f\u043e\u0434\u0437\u0430\u0434\u0430\u0447\u0438. <\/p>\n<ol>\n<li>\u0417\u0430\u0433\u0440\u0443\u0437\u0438\u0442\u044c \u0444\u043e\u0442\u043e\u0433\u0440\u0430\u0444\u0438\u044e \u0438\u0437 \u0433\u0430\u043b\u0435\u0440\u0435\u0438<\/li>\n<li>\u0421\u043e\u0437\u0434\u0430\u0442\u044c \u043a\u043e\u043b\u043b\u0435\u043a\u0446\u0438\u044e \u0441 \u0444\u0438\u043b\u044c\u0442\u0440\u0430\u043c\u0438<\/li>\n<li>\u0420\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u0442\u044c \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u043f\u0440\u0438\u043c\u0435\u043d\u044f\u0442\u044c \u043b\u044e\u0431\u043e\u0439 \u0438\u0437 \u0444\u0438\u043b\u044c\u0442\u0440\u043e\u0432 \u043d\u0430 \u0432\u044b\u0431\u0440\u0430\u043d\u043d\u0443\u044e \u043d\u0430\u043c\u0438 \u0444\u043e\u0442\u043e\u0433\u0440\u0430\u0444\u0438\u044e<\/li>\n<li> \u0421\u043e\u0445\u0440\u0430\u043d\u0438\u0442\u044c \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u0432 \u0433\u0430\u043b\u0435\u0440\u0435\u044e.<\/li>\n<\/ol>\n<p>  <a name=\"habracut\"><\/a><\/p>\n<p>  \u0418\u0442\u0430\u043a, \u043f\u0440\u0438\u0441\u0442\u0443\u043f\u0438\u043c. \u041e\u0442\u043a\u0440\u044b\u0432\u0430\u0435\u043c Xcode \u0438 \u0432\u044b\u0431\u0438\u0440\u0430\u0435\u043c \u0448\u0430\u0431\u043b\u043e\u043d \u0434\u043b\u044f \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u043f\u043e\u0434 iOS \u0432\u043e \u0432\u043a\u043b\u0430\u0434\u043a\u0435 Application -&gt; Single View Application. \u041d\u0430\u0437\u043e\u0432\u0435\u043c \u043d\u0430\u0448 \u043f\u0440\u043e\u0435\u043a\u0442 My First Photo Editor. \u0414\u0430\u043b\u0435\u0435 \u0443\u043a\u0430\u0436\u0435\u043c \u0434\u0438\u0440\u0435\u043a\u0442\u043e\u0440\u0438\u044e, \u043a\u0443\u0434\u0430 \u0445\u043e\u0442\u0438\u043c \u0441\u043e\u0445\u0440\u0430\u043d\u0438\u0442\u044c \u043f\u0440\u043e\u0435\u043a\u0442.<\/p>\n<p>  <img decoding=\"async\" src=\"https:\/\/habrastorage.org\/files\/446\/e94\/447\/446e94447d334efb8ed66fe82d0d4d3e.PNG\"\/><\/p>\n<p>  <img decoding=\"async\" src=\"https:\/\/habrastorage.org\/files\/ec1\/625\/9ce\/ec16259ce06842b98b868a897809a8b6.PNG\"\/><\/p>\n<p>  \u0412\u044b\u0431\u0435\u0440\u0435\u043c \u043c\u0435\u0445\u0430\u043d\u0438\u0437\u043c \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u0430 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u044b main.storyboard.<\/p>\n<p>  <img decoding=\"async\" src=\"https:\/\/habrastorage.org\/files\/b3f\/a8e\/934\/b3fa8e934edb4a0a96369af1c61f32c7.PNG\"\/><\/p>\n<p>  \u041d\u0430\u043c \u043f\u0440\u0438\u0434\u0435\u0442\u0441\u044f \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u0438\u0442\u044c \u0438 \u043d\u0430 \u0434\u0440\u0443\u0433\u0438\u0435 \u0441\u0446\u0435\u043d\u044b, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0431\u0443\u0434\u0443\u0442 \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0442\u044c\u0441\u044f \u043f\u043e\u0437\u0436\u0435. \u0414\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u043f\u0435\u0440\u0435\u0442\u0430\u0449\u0438\u043c Navigation Controller \u043d\u0430 storyboard. <\/p>\n<p>  <img decoding=\"async\" src=\"https:\/\/habrastorage.org\/files\/41a\/05e\/4db\/41a05e4db7bf45eea4152a1a93f5fe9f.PNG\"\/><\/p>\n<p>  \u0423\u0434\u0430\u043b\u0438\u043c Root View Controller Scene \u2013 \u043e\u043d \u043d\u0430\u043c \u043d\u0435 \u043f\u043e\u043d\u0430\u0434\u043e\u0431\u0438\u0442\u0441\u044f. \u0422\u0435\u043f\u0435\u0440\u044c \u043e\u0441\u0442\u0430\u043b\u043e\u0441\u044c \u0441\u0432\u044f\u0437\u0430\u0442\u044c Navigation Controller c \u0438\u0441\u0445\u043e\u0434\u043d\u044b\u043c View Controller.<\/p>\n<p>  <img decoding=\"async\" src=\"https:\/\/habrastorage.org\/files\/e20\/f4d\/71b\/e20f4d71b49e47f3b7df5ab9ed80a40b.PNG\"\/><\/p>\n<p>  <img decoding=\"async\" src=\"https:\/\/habrastorage.org\/files\/cf1\/fe1\/bbe\/cf1fe1bbeca344e5ba56df1d2182c9ed.PNG\"\/><\/p>\n<p>  \u0412\u044b\u0431\u0438\u0440\u0430\u0435\u043c Navigation Controller, \u0441\u0442\u0430\u0432\u0438\u043c \u0433\u0430\u043b\u043e\u0447\u043a\u0443 \u043d\u0430\u043f\u0440\u043e\u0442\u0438\u0432 \u00abIs Initial View Controller\u00bb (Navigation Controller &gt; Attributes Inspector &gt; View Controller &gt; Is Initial View Controller; \u043d\u0430 \u043a\u0430\u0440\u0442\u0438\u043d\u043a\u0430\u0445 \u043c\u043e\u0436\u043d\u043e \u0443\u0432\u0438\u0434\u0435\u0442\u044c, \u043a\u0430\u043a \u044d\u0442\u043e \u0441\u0434\u0435\u043b\u0430\u0442\u044c) \u0438 \u0441\u0432\u044f\u0437\u044b\u0432\u0430\u0435\u043c Navigation Controller \u0441 View Controller.<\/p>\n<p>  \u041d\u0430 View Controller \u043d\u0430\u043c \u043f\u043e\u043d\u0430\u0434\u043e\u0431\u0438\u0442\u0441\u044f \u043a\u043d\u043e\u043f\u043a\u0430 \u0434\u043b\u044f \u043e\u0442\u043a\u0440\u044b\u0442\u0438\u044f \u043e\u043a\u043d\u0430 \u0433\u0430\u043b\u0435\u0440\u0435\u0438. \u041f\u0435\u0440\u0435\u043d\u0435\u0441\u0435\u043c \u0435\u0435 \u0438\u0437 Object Library.<\/p>\n<p>  <img decoding=\"async\" src=\"https:\/\/habrastorage.org\/files\/bd1\/dcf\/c5d\/bd1dcfc5d686473bb2d6a848c9ddec2b.PNG\"\/><\/p>\n<p>  \u0421\u043e\u0437\u0434\u0430\u0434\u0438\u043c \u0441\u043e\u0431\u044b\u0442\u0438\u0435 \u043d\u0430\u0436\u0430\u0442\u0438\u044f \u043d\u0430 \u043a\u043d\u043e\u043f\u043a\u0443 \u0438 \u0434\u043e\u0431\u0430\u0432\u0438\u043c \u0435\u0433\u043e \u0432 \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u0430 \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440\u0430.<\/p>\n<p>  <img decoding=\"async\" src=\"https:\/\/habrastorage.org\/files\/c35\/4b6\/e4e\/c354b6e4e00a4cef8a334b3603111a96.PNG\"\/> <\/p>\n<p>  <img decoding=\"async\" src=\"https:\/\/habrastorage.org\/files\/d39\/bd2\/dc7\/d39bd2dc7315400e91571fe8d6f28f52.PNG\"\/><\/p>\n<p>  \u0422\u0430\u043a \u043a\u0430\u043a \u043c\u044b \u0431\u0443\u0434\u0435\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0434\u0435\u043b\u0435\u0433\u0430\u0442\u043d\u044b\u0435 \u043c\u0435\u0442\u043e\u0434\u044b, \u0434\u043e\u0431\u0430\u0432\u0438\u043c \u0432 \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441 \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440\u0430 ViewConroller.h \u043f\u0440\u043e\u0442\u043e\u043a\u043e\u043b\u044b \u0434\u0435\u043b\u0430\u0433\u0430\u0442\u043e\u0432 UIImagePickerControllerDelegate,UINavigationControllerDelegate<\/p>\n<p>  \u041f\u043e\u043b\u0443\u0447\u0430\u0435\u0442\u0441\u044f:<\/p>\n<pre><code class=\"objectivec\">@interface ViewController : UIViewController&lt;UIImagePickerControllerDelegate,UINavigationControllerDelegate&gt;<\/code><\/pre>\n<p>  \u041f\u0440\u043e\u043f\u0438\u0448\u0435\u043c \u0432 \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0438 \u043a\u043d\u043e\u043f\u043a\u0438 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0435 \u0441\u0442\u0440\u043e\u043a\u0438:<\/p>\n<pre><code class=\"objectivec\"> - (IBAction)btnOpen_pressed:(id)sender { UIImagePickerController *picker = [[UIImagePickerControlleralloc] init]; picker.delegate = self;     [pickersetSourceType:UIImagePickerControllerSourceTypePhotoLibrary];     [selfpresentViewController:picker animated:YEScompletion:nil];\/\/ \u0432\u044b\u0437\u043e\u0432 \u043e\u043a\u043d\u0430 \u0433\u0430\u043b\u0435\u0440\u0435\u0438 }  <\/code><\/pre>\n<p>  \u2028<br \/>  \u0417\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u043c \u043f\u0440\u043e\u0435\u043a\u0442 \u0438 \u0432\u0438\u0434\u0438\u043c \u043d\u0430 \u0441\u0438\u043c\u0443\u043b\u044f\u0442\u043e\u0440\u0435 \u043d\u0430\u0448\u0443 \u043a\u043d\u043e\u043f\u043a\u0443. \u041f\u043e\u043f\u0440\u043e\u0431\u0443\u0435\u043c \u043d\u0430\u0436\u0430\u0442\u044c \u0438\u2026 \u043f\u043e\u043b\u0443\u0447\u0438\u043c \u043a\u0440\u0430\u0448. \u041f\u043e\u0447\u0435\u043c\u0443? \u041c\u044b \u0437\u0430\u0431\u044b\u043b\u0438 \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u043e \u0432 info.plist NSPhotoLibraryUsageDescription. \u0418\u0441\u043f\u0440\u0430\u0432\u0438\u043c \u044d\u0442\u0443 \u043e\u0448\u0438\u0431\u043a\u0443.<\/p>\n<p>  <img decoding=\"async\" src=\"https:\/\/habrastorage.org\/files\/116\/9c9\/925\/1169c9925a204abca5300c333d4fecef.png\"\/><\/p>\n<p>  \u0422\u0435\u043f\u0435\u0440\u044c \u043d\u0443\u0436\u043d\u043e \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u043d\u0430 storyboard \u0435\u0449\u0435 \u043e\u0434\u0438\u043d View Controller. \u0421\u0434\u0435\u043b\u0430\u0435\u043c \u0441\u0432\u044f\u0437\u044c \u043f\u043e \u0441\u0445\u0435\u043c\u0435, \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u043d\u043e\u0439 \u043d\u0430 \u0441\u043a\u0440\u0438\u043d\u0448\u043e\u0442\u0430\u0445.<\/p>\n<p>  <img decoding=\"async\" src=\"https:\/\/habrastorage.org\/files\/aac\/2a6\/a4e\/aac2a6a4e6754f2ea9b9e0296b18b287.PNG\"\/><\/p>\n<p>  <img decoding=\"async\" src=\"https:\/\/habrastorage.org\/files\/523\/a54\/9cc\/523a549cc943479683bcf7acafa4b53b.PNG\"\/><\/p>\n<p>  \u041f\u0440\u043e\u043f\u0438\u0448\u0435\u043c Indetifier \u043a\u043b\u044e\u0447 \u00abtoFilters\u00bb. \u041d\u0430 \u0438\u043b\u043b\u044e\u0441\u0442\u0440\u0430\u0446\u0438\u0438 \u043f\u043e\u043a\u0430\u0437\u0430\u043d\u043e, \u043a\u0430\u043a \u044d\u0442\u043e \u043c\u043e\u0436\u043d\u043e \u0441\u0434\u0435\u043b\u0430\u0442\u044c. \u0412\u044b\u0431\u0435\u0440\u0435\u043c \u0441\u0432\u044f\u0437\u044c \u043d\u0430 Storyboard &gt; Attributes Inspector &gt;Storyboard &gt; identifier &gt; toFilters.<\/p>\n<p>  <img decoding=\"async\" src=\"https:\/\/habrastorage.org\/files\/acc\/eff\/fd5\/accefffd584f4be688b132c04ebd6b61.PNG\"\/><\/p>\n<p>  \u0422\u0435\u043f\u0435\u0440\u044c \u0434\u043e\u0431\u0430\u0432\u0438\u043c \u0432\u043e ViewController.m \u043c\u0435\u0442\u043e\u0434\u044b \u0432\u044b\u0431\u043e\u0440\u0430 \u0444\u043e\u0442\u043e \u0438 \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u0430 \u043d\u0430 \u043d\u043e\u0432\u044b\u0439 \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440.<\/p>\n<pre><code class=\"objectivec\"> \/\/ \u0434\u0435\u043b\u0430\u0433\u0430\u0442\u043d\u044b\u0439 \u043c\u0435\u0442\u043e\u0434, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u043f\u043e\u0441\u043b\u0435 \u0432\u044b\u0431\u043e\u0440\u0430 \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044f -(void)imagePickerController:(UIImagePickerController *)picker didFinishPickingImage:(UIImage *)image editingInfo:(NSDictionary *)editingInfo {     [pickerdismissViewControllerAnimated:YEScompletion:nil]; self.btnOpenPhoto.enabled = NO;   dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{  self.selectedImage = image; dispatch_async(dispatch_get_main_queue(), ^{             [selfperformSegueWithIdentifier:kFiltersSegueIdsender:self]; self.btnOpenPhoto.enabled = YES;          });     });  } \/\/ \u0434\u0435\u043b\u0430\u0433\u0430\u0442\u043d\u044b\u0439 \u043c\u0435\u0442\u043e\u0434, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u043f\u0440\u0438 \u043e\u0442\u043c\u0435\u043d\u0435 \u0432\u044b\u0431\u043e\u0440\u0430 \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044f -(void) imagePickerControllerDidCancel:(UIImagePickerController *)picker {     [pickerdismissViewControllerAnimated:YEScompletion:nil]; }   #pragma mark - segue \/\/ \u042d\u0442\u043e\u0442 \u043c\u0435\u0442\u043e\u0434 \u0431\u0443\u0434\u0435\u0442 \u0432\u044b\u0437\u0432\u0430\u043d \u0443 \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440\u0430, \u0438\u0437 \u043a\u043e\u0442\u043e\u0440\u043e\u0433\u043e \u0431\u044b\u043b \u043d\u0430\u0447\u0430\u0442 \u043f\u0435\u0440\u0435\u0445\u043e\u0434  -(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {\/\/kFiltersSegueId \u2013 \u044d\u0442\u043e \u043a\u043e\u043d\u0441\u0442\u0430\u043d\u0442\u0430 \u0442\u0438\u043f\u0430 String \u0441 \u0438\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440\u043e\u043c \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u0430 \u00abtoFilters\u00bb if ([segue.identifierisEqualToString:kFiltersSegueId])     { FiltersViewController *destinationController = (FiltersViewController *)segue.destinationViewController; destinationController.image = self.selectedImage;     } }<\/code><\/pre>\n<p>   <img decoding=\"async\" src=\"https:\/\/habrastorage.org\/files\/12d\/772\/67a\/12d77267af1a44149838c0248c3902b5.PNG\"\/><\/p>\n<p>  <img decoding=\"async\" src=\"https:\/\/habrastorage.org\/files\/ab0\/49a\/f00\/ab049af00c0f412991aba1b84030192f.PNG\"\/><\/p>\n<p>  \u0414\u043b\u044f \u043d\u043e\u0432\u043e\u0433\u043e \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440\u0430 \u043d\u0430\u043c \u043d\u0443\u0436\u043d\u043e \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u043e\u0441\u043e\u0431\u044b\u0439 \u043a\u043b\u0430\u0441\u0441. \u0414\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u0432 \u0432\u0435\u0440\u0445\u043d\u0435\u0439 \u043f\u0430\u043d\u0435\u043b\u0438 \u0432\u044b\u0431\u0438\u0440\u0430\u0435\u043c File-&gt;New-&gt;File-&gt;Cocoa Touch Class-&gt;Next. \u041d\u0430\u0437\u043e\u0432\u0435\u043c \u0435\u0433\u043e FiltersViewController \u0438 \u043e\u0431\u044f\u0437\u0430\u0442\u0435\u043b\u044c\u043d\u043e \u0432\u044b\u0431\u0435\u0440\u0435\u043c \u0432 \u0433\u0440\u0430\u0444\u0435 Subclass UIViewController. \u0412 Indetity inspector \u043f\u0440\u043e\u043f\u0438\u0441\u044b\u0432\u0430\u0435\u043c \u043d\u0430\u0448 \u043a\u043b\u0430\u0441\u0441. <\/p>\n<p>  <img decoding=\"async\" src=\"https:\/\/habrastorage.org\/files\/c87\/0c7\/1ef\/c870c71efe13408eae26f9ef5ecbc28a.PNG\"\/><\/p>\n<p>  \u0414\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c \u043d\u0430 \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440 Scroll View (\u0438\u043b\u0438 \u043a\u0430\u043a\u0443\u044e-\u043d\u0438\u0431\u0443\u0434\u044c \u0434\u0440\u0443\u0433\u0443\u044e View, \u043d\u0430 \u0432\u0430\u0448\u0435 \u0443\u0441\u043c\u043e\u0442\u0440\u0435\u043d\u0438\u0435), \u0432 \u043d\u0435\u043c \u0431\u0443\u0434\u0435\u0442 \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0430\u0442\u044c\u0441\u044f \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0435 \u0441 \u043f\u0440\u0438\u043c\u0435\u043d\u043d\u0435\u043d\u044b\u043c \u0444\u0438\u043b\u044c\u0442\u0440\u043e\u043c. \u0421\u043e\u0437\u0434\u0430\u0435\u043c \u0441\u0432\u044f\u0437\u044c \u0441 FiltersViewController. <\/p>\n<p>  <img decoding=\"async\" src=\"https:\/\/habrastorage.org\/files\/65d\/738\/a87\/65d738a87bb54deea146f15fde56c870.PNG\"\/><\/p>\n<p>  <img decoding=\"async\" src=\"https:\/\/habrastorage.org\/files\/401\/c53\/929\/401c53929cd74d9bbb972938137b8961.png\"\/><\/p>\n<p>  \u0414\u043e\u0431\u0430\u0432\u0438\u043c Scroll View \u0432 \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u0430 \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u0435\u0440\u0430, \u043a\u0430\u043a \u0434\u0435\u043b\u0430\u043b\u0438 \u0440\u0430\u043d\u0435\u0435. \u0414\u043e\u0431\u0430\u0432\u0438\u043c \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u0430 UIImageView \u0438 UIimage.<\/p>\n<p>  <img decoding=\"async\" src=\"https:\/\/habrastorage.org\/files\/1d0\/66a\/4e0\/1d066a4e0b2d4f439cb9b72ca603221e.PNG\"\/><\/p>\n<p>  \u041f\u0440\u0438 \u044d\u0442\u043e\u043c \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u043e UIImage \u043d\u0443\u0436\u043d\u043e \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0432 FiltersViewController.h, \u0442\u0430\u043a \u043a\u0430\u043a \u043c\u044b \u043f\u043b\u0430\u043d\u0438\u0440\u0443\u0435\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0435\u0433\u043e \u0432 \u0434\u0440\u0443\u0433\u043e\u043c \u043a\u043b\u0430\u0441\u0441\u0435.<\/p>\n<p>  \u0422\u0435\u043f\u0435\u0440\u044c \u0441\u043e\u0437\u0434\u0430\u0434\u0438\u043c \u043a\u043e\u043b\u043b\u0435\u043a\u0446\u0438\u044e \u0441 \u0444\u0438\u043b\u044c\u0442\u0440\u0430\u043c\u0438. \u041d\u0430\u0445\u043e\u0434\u0438\u043c \u0432 Object Library \u043e\u0431\u044a\u0435\u043a\u0442 Collection View. <\/p>\n<p>  <img decoding=\"async\" src=\"https:\/\/habrastorage.org\/files\/5fb\/72f\/67c\/5fb72f67cd29455e84ed12318b23a005.PNG\"\/><\/p>\n<p>  <img decoding=\"async\" src=\"https:\/\/habrastorage.org\/files\/c04\/bff\/283\/c04bff28334b4b2f976fd8e144ef8e2d.PNG\"\/><\/p>\n<p>  <img decoding=\"async\" src=\"https:\/\/habrastorage.org\/files\/93c\/37d\/db9\/93c37ddb9d344dad8f51e0c5402ab4fd.PNG\"\/><\/p>\n<p>  \u0421\u043e\u0437\u0434\u0430\u0435\u043c \u043d\u043e\u0432\u044b\u0439 \u043a\u043b\u0430\u0441\u0441 \u0434\u043b\u044f \u043a\u043e\u043b\u043b\u0435\u043a\u0446\u0438\u0438. \u0417\u0430\u0445\u043e\u0434\u0438\u043c \u0432 xib \u0444\u0430\u0439\u043b, \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c UIimageView \u0438 Label. <br \/>  \u0414\u043b\u0430\u0435\u0435 \u0437\u0430\u0434\u0430\u0434\u0438\u043c \u0440\u0430\u0437\u043c\u0435\u0440\u044b UIImageView. \u0421\u0430\u043c\u044b\u0439 \u043f\u0440\u043e\u0441\u0442\u043e\u0439 \u0441\u043f\u043e\u0441\u043e\u0431 \u044d\u0442\u043e \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u2013 \u0437\u0430\u0436\u0430\u0442\u044c \u043f\u0440\u0430\u0432\u043e\u0439 \u043a\u043b\u0430\u0432\u0438\u0448\u0435\u0439 \u043e\u0431\u044a\u0435\u043a\u0442 \u0438 \u043f\u0435\u0440\u0435\u0442\u0430\u0449\u0438\u0442\u044c \u0435\u0433\u043e \u043d\u0430 \u0442\u043e\u0442, \u043a \u043a\u043e\u0442\u043e\u0440\u043e\u043c\u0443 \u0445\u043e\u0442\u0438\u043c \u043f\u0440\u0438\u0432\u044f\u0437\u0430\u0442\u044c. \u0412\u044b\u0431\u0438\u0440\u0430\u0435\u043c \u0441\u0432\u044f\u0437\u0438, \u043a\u0430\u043a \u043f\u043e\u043a\u0430\u0437\u0430\u043d\u043e \u043d\u0430 \u0441\u043a\u0440\u0438\u043d\u0448\u043e\u0442\u0435. \u0417\u0430\u0442\u0435\u043c \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u0438\u043c \u0432 Size inspector \u044d\u0442\u043e\u0433\u043e \u043e\u0431\u044a\u0435\u043a\u0442\u0430 \u0438 \u0438\u0437\u043c\u0435\u043d\u044f\u0435\u043c \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438. \u0412\u044b\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u043c \u0432\u0441\u0435 constraints \u0432 0.<\/p>\n<p>  <img decoding=\"async\" src=\"https:\/\/habrastorage.org\/files\/45e\/648\/664\/45e648664fdf420a8365e64b5338c629.PNG\"\/><\/p>\n<p>  \u0423\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u0435\u043c \u0441\u0432\u044f\u0437\u044c \u043c\u0435\u0436\u0434\u0443 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u0430\u043c\u0438. <\/p>\n<p>  <img decoding=\"async\" src=\"https:\/\/habrastorage.org\/files\/552\/677\/588\/552677588d304c7cb3c6b6534a8274af.PNG\"\/><\/p>\n<p>  \u0418\u043c\u043f\u043e\u0440\u0442\u0438\u0440\u0443\u0435\u043c \u043d\u043e\u0432\u044b\u0439 \u043a\u043b\u0430\u0441\u0441 \u0432 FiltersViewController <\/p>\n<p>  <img decoding=\"async\" src=\"https:\/\/habrastorage.org\/files\/927\/da8\/227\/927da8227420474c8b0f631eb26d16a5.PNG\"\/><\/p>\n<p>  \u0438 \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c FiltersViewControllerCell \u0432 \u044d\u0442\u043e\u0442 \u043a\u043b\u0430\u0441\u0441 \u0432\u043e\u0442 \u0442\u0430\u043a\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c:<\/p>\n<p>  <img decoding=\"async\" src=\"https:\/\/habrastorage.org\/files\/241\/db8\/7f0\/241db87f0cfe4048b2f6e3f8a26d0b82.PNG\"\/><\/p>\n<p>  \u0422\u0435\u043f\u0435\u0440\u044c \u0434\u043e\u0431\u0430\u0432\u0438\u043c \u0432 \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u0430 FiltersViewController \u043c\u0430\u0441\u0441\u0438\u0432 NSMutableArray \u0438 \u043e\u043f\u0435\u0440\u0430\u0442\u043e\u0440 NSOperationQueue \u2013 \u043e\u043d\u0438 \u043d\u0430\u043c \u043f\u0440\u0438\u0433\u043e\u0434\u044f\u0442\u0441\u044f \u0447\u0443\u0442\u044c \u043f\u043e\u0437\u0436\u0435.<\/p>\n<p>  <img decoding=\"async\" src=\"https:\/\/habrastorage.org\/files\/6a9\/2ae\/6a6\/6a92ae6a64634803be9afda9b4b97ea4.PNG\"\/><\/p>\n<p>  \u0416\u0438\u0437\u043d\u0435\u043d\u043d\u044b\u0439 \u0446\u0438\u043a\u043b UIViewController \u043d\u0430\u0447\u0438\u043d\u0430\u0435\u0442\u0441\u044f \u0441 \u043c\u0435\u0442\u043e\u0434\u0430 loadView. \u0410 \u0437\u043d\u0430\u0447\u0438\u0442, \u0432 \u044d\u0442\u043e\u043c \u043c\u0435\u0442\u043e\u0434\u0435 \u043d\u0430\u043c \u043d\u0443\u0436\u043d\u043e \u043f\u0435\u0440\u0435\u0434\u0430\u0442\u044c \u043a\u0430\u0440\u0442\u0438\u043d\u043a\u0443, \u043a\u043e\u0442\u043e\u0440\u0443\u044e \u043c\u044b \u0432\u044b\u0431\u0440\u0430\u043b\u0438 \u043d\u0430 \u043f\u0440\u043e\u0448\u043b\u043e\u0439 \u0441\u0446\u0435\u043d\u0435, \u0438 \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u043f\u0440\u0435\u0432\u044c\u044e \u0432 \u043a\u043e\u043b\u043b\u0435\u043a\u0446\u0438\u044e.<\/p>\n<p>  \u0412 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u0435 loadView \u0431\u0443\u0434\u0435\u0442 \u0432\u044b\u0433\u043b\u044f\u0434\u0435\u0442\u044c \u0442\u0430\u043a:  <\/p>\n<pre><code class=\"objectivec\">- (void)loadView{      [super loadView];     self.automaticallyAdjustsScrollViewInsets = NO;     [[NSNotificationCenter defaultCenter] addObserver:selfselector:@selector(orientationChanged:) name:UIDeviceOrientationDidChangeNotificationobject:[UIDevice currentDevice]];          if ([self.navigationController respondsToSelector:@selector(interactivePopGestureRecognizer)]) {         self.navigationController.interactivePopGestureRecognizer.enabled = NO;     }          _imageView = [[UIImageView alloc] init];     [_scrollView addSubview:_imageView];     _imageView.image = _image;     _imageView.frame = CGRectMake(0, 0, _image.size.width, _image.size.height);          _filteringQueue = [NSOperationQueue new];     _filteringQueue.maxConcurrentOperationCount = 1;     _filteringQueue.qualityOfService = NSQualityOfServiceUserInitiated;   [self.filtersCollection registerNib:[UINib nibWithNibName:@&quot;FiltersCollectionViewCell&quot; bundle:nil] forCellWithReuseIdentifier:@&quot;filtersCollectionCell\u00bb];\/\/\u0420\u0435\u0433\u0438\u0441\u0442\u0440\u0438\u0440\u0443\u0435\u043c  xib \u0444\u0430\u0439\u043b \u0434\u043b\u044f \u043a\u043e\u043b\u043b\u0435\u043a\u0446\u0438\u0438.     \/\/ Do any additional setup after loading the view. } \u2028<\/code><\/pre>\n<p>  \u0427\u0442\u043e\u0431\u044b \u043d\u0435 \u043f\u0435\u0440\u0435\u0437\u0430\u0433\u0440\u0443\u0436\u0430\u0442\u044c \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440, \u0441\u043e\u0437\u0434\u0430\u0434\u0438\u043c \u043a\u043b\u0430\u0441\u0441 Extension \u0438 \u0434\u043e\u0431\u0430\u0432\u0438\u043c \u0432 \u043d\u0435\u0433\u043e \u043c\u0435\u0442\u043e\u0434\u044b, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0431\u0443\u0434\u0443\u0442 \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0442\u044c \u0444\u0443\u043d\u043a\u0446\u0438\u044e \u043d\u0430\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u0444\u0438\u043b\u044c\u0442\u0440\u0430 \u043d\u0430 \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0435:<\/p>\n<pre><code class=\"objectivec\">#import &quot;Extension.h&quot;  @implementation CIImage (Extension)  -(CIImage *)applyFilter:(long)i {     CIFilter *filter;          switch (i) {         case 0:             return [self copy];             break;         case 1:             filter = [CIFilter filterWithName:@&quot;CISepiaTone&quot;];             break;         case 2:             filter = [CIFilter filterWithName:@&quot;CIColorMonochrome&quot;];             break;         case 3:             filter = [CIFilter filterWithName:@&quot;CIPhotoEffectMono&quot;];             break;         case 4:             filter = [CIFilter filterWithName:@&quot;CIPhotoEffectInstant&quot;];             break;         case 5:             filter = [CIFilter filterWithName:@&quot;CIHueAdjust&quot;];             [filter setDefaults];             [filter setValue: [NSNumber numberWithFloat: M_PI] forKey: kCIInputAngleKey];             break;         case 6:             filter = [CIFilter filterWithName:@&quot;CIHueAdjust&quot;];             [filter setDefaults];             [filter setValue: [NSNumber numberWithFloat: M_PI_2] forKey: kCIInputAngleKey];             break;         case 7:             filter = [CIFilter filterWithName:@&quot;CIColorInvert&quot;];             break;         case 8:             filter = [CIFilter filterWithName:@&quot;CIFalseColor&quot;];             break;         case 9:             filter = [CIFilter filterWithName:@&quot;CIPhotoEffectTonal&quot;];             break;         case 10:             filter= [CIFilter filterWithName:@&quot;CIPhotoEffectTransfer&quot;];             break;         case 11:             filter= [CIFilter filterWithName:@&quot;CIPhotoEffectProcess&quot;];             break;         case 12:             filter= [CIFilter filterWithName:@&quot;CIPhotoEffectChrome&quot;];             break;         case 13:             filter = [CIFilter filterWithName:@&quot;CIGaussianBlur&quot;];             [filter setDefaults];             [filter setValue: [NSNumber numberWithFloat:(self.extent.size.width + self.extent.size.height)\/30.] forKey:@&quot;inputRadius&quot;];         default:             break;     }          [filter setValue:self forKey:kCIInputImageKey];     CIImage *result = [filter valueForKey:kCIOutputImageKey];     return result; } @end   @implementation UIImage (Extension)   +(NSArray *)filterNames {     static NSArray *names;     static dispatch_once_t onceToken;     dispatch_once(&onceToken, ^{         names = @[@&quot;Original&quot;,@&quot;Sepia&quot;, @&quot;Old Photo&quot;, @&quot;Mono&quot;, @&quot;Instant&quot;, @&quot;Shift&quot;, @&quot;Hue&quot;, @&quot;Invert&quot;, @&quot;Falce&quot;, @&quot;Tonal&quot;, @&quot;Transfer&quot;, @&quot;Process&quot;, @&quot;Chrome&quot;];     });     return names; } - (UIImage *)applyFilter:(long)i {     CIImage *ciImage = [[CIImage alloc] initWithImage: self];     CIImage *result = [ciImage applyFilter:i];     CGRect extent1 = [result extent];     CIContext *context = [CIContext contextWithOptions:nil];     CGImageRef cgImage1 = [context createCGImage:result fromRect:extent1];     UIImage *img = [UIImage imageWithCGImage:cgImage1];     CGImageRelease(cgImage1);     return img; }    + (instancetype)imageWithCIImageImproved:(CIImage *)img {     CGRect extent = [img extent];     CIContext *context = [CIContext contextWithOptions:nil];     CGImageRef cgImage = [context createCGImage:img fromRect:extent];     UIImage *image = [UIImage imageWithCGImage:cgImage];     CGImageRelease(cgImage);     return image; }  @end<\/code><\/pre>\n<p>  \u0434\u0430\u043b\u0435\u0435 \u043f\u0440\u043e\u043f\u0438\u0448\u0435\u043c \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441 \u0432\u044b\u0437\u043e\u0432\u043e\u0432 \u0432 Extension.h:<\/p>\n<pre><code class=\"objectivec\">#import &lt;UIKit\/UIKit.h&gt;  @interface CIImage (Extension) -(CIImage *)applyFilter:(long)i; @end  @interface UIImage (Extension)  @property (class, readonly) NSArray * filterNames;  + (NSArray *)filterNames; - (UIImage *)applyFilter:(long)i; + (instancetype)imageWithCIImageImproved:(CIImage *)img; @end<\/code><\/pre>\n<p>  \u0414\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0435 \u043c\u0435\u0442\u043e\u0434\u044b \u0434\u043b\u044f \u043a\u043e\u043b\u043b\u0435\u043a\u0446\u0438\u0438 \u0438 \u0434\u043b\u044f Scroll View \u0432 \u043a\u043b\u0430\u0441\u0441 FiltersViewController.m:<\/p>\n<pre><code class=\"objectivec\">#pragma mark - Collection \/\/ \u0412\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u044f\u0447\u0435\u0435\u043a \u0434\u043b\u044f \u0441\u0435\u043a\u0446\u0438\u0438, \u043e\u0431\u044f\u0437\u0430\u0442\u0435\u043b\u044c\u043d\u044b\u0439 \u043c\u0435\u0442\u043e\u0434  -(NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section { returnself.filterPreviews.count; }\u2028 \/\/ \u0412\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u0440\u0430\u0437\u043c\u0435\u0440 \u044f\u0447\u0435\u0439\u043a\u0438  - (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath { CGFloat sz = collectionView.frame.size.height - 6; returnCGSizeMake(sz, sz); }\u2028 \/\/\u041e\u0431\u044f\u0437\u0430\u0442\u0435\u043b\u044c\u043d\u044b\u0439 \u043c\u0435\u0442\u043e\u0434, \u0432 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u043a\u043e\u0442\u043e\u0440\u043e\u0433\u043e \u043c\u044b \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u043c \u0441\u043e\u0437\u0434\u0430\u043d\u043d\u044b\u0439 \u0438 \u0441\u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0439 \u043e\u0431\u044a\u0435\u043a\u0442 UICollectionViewCell -(UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath { long index = [indexPath item]; FiltersCollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:@&quot;filtersCollectionCell&quot;forIndexPath:indexPath];  UIImageView *ivPreview = cell.imageFilter; ivPreview.image = self.filterPreviews[index]; ivPreview.clipsToBounds = YES; ivPreview.layer.cornerRadius = 3.; UILabel *labelName = cell.nameFilter; labelName.text = [UIImagefilterNames][index];    return cell; } \/\/ \u043c\u0435\u0442\u043e\u0434, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f, \u0435\u0441\u043b\u0438 \u044f\u0447\u0435\u0439\u043a\u0430 \u0431\u044b\u043b\u0430 \u0443\u0441\u043f\u0435\u0448\u043d\u043e \u0432\u044b\u0431\u0440\u0430\u043d\u0430 - (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath {      [self.filteringQueuecancelAllOperations];  __blockUIImage *filtered = nil; NSBlockOperation *operation1 = [NSBlockOperationblockOperationWithBlock:^{ filtered = [self.imageapplyFilter:[indexPath item]];     }]; NSBlockOperation *operation2 = [NSBlockOperationblockOperationWithBlock:^{         [CATransactionbegin]; dispatch_sync(dispatch_get_main_queue(), ^{ if (filtered) { _imageView.image = filtered;             } \t\t   });     }];     [operation2addDependency:operation1];     [self.filteringQueueaddOperation:operation1];     [self.filteringQueueaddOperation:operation2]; }\u2028 #pragma mark - Scroll View \/\/ \u043c\u0435\u0442\u043e\u0434 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u043e\u0431\u044a\u0435\u043a\u0442 UIView, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c\u044b\u0439 \u043f\u0440\u0438 \u043c\u0430\u0441\u0448\u0442\u0430\u0431\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0438 \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u043c\u043e\u0433\u043e -(UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView { returnself.imageView; } \/\/ \u0434\u0435\u043b\u0435\u0433\u0430\u0442\u043d\u044b\u0439 \u043c\u0435\u0442\u043e\u0434, \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u043c\u044b\u0439 \u0432\u043e \u0432\u0440\u0435\u043c\u044f \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f \u043c\u0430\u0441\u0448\u0442\u0430\u0431\u0430 \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u043c\u043e\u0433\u043e - (void)scrollViewDidZoom:(UIScrollView *)scrollView { CGSize sz = scrollView.contentSize;  float xInsets = MAX(0, scrollView.frame.size.width\/2.-sz.width\/2.); float yInsets = MAX(0, scrollView.frame.size.height\/2.-sz.height\/2.);     [scrollViewsetContentInset:UIEdgeInsetsMake(yInsets,xInsets,yInsets,xInsets)]; }\u2028 \/\/ \u043c\u0435\u0442\u043e\u0434, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u043f\u0440\u0438 \u0441\u043c\u0435\u043d\u0435 \u043e\u0440\u0438\u0435\u043d\u0442\u0430\u0446\u0438\u0438 - (void) orientationChanged:(NSNotification *)note {     [self.viewlayoutSubviews];     [selfupdateScaleInScrollView:self.scrollView]; } \/\/ \u043c\u0435\u0442\u043e\u0434, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043a\u043e\u0440\u0440\u0435\u043a\u0442\u043d\u043e \u0432\u044b\u0432\u043e\u0434\u0438\u0442 \u0441\u043e\u0434\u0435\u0440\u0435\u0436\u0438\u043c\u043e\u0435 ScrollView \u043f\u043e\u0441\u043b\u0435 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f \u043c\u0430\u0441\u0448\u0442\u0430\u0431\u0430 -(void)updateScaleInScrollView:(UIScrollView *)scrollView { UIImage *image = _image; float minScale = sizeFit(image.size,scrollView.frame.size).width\/image.size.width; scrollView.maximumZoomScale = MAX(1,minScale); scrollView.minimumZoomScale = minScale; scrollView.zoomScale = minScale;  if (scrollView.zoomScale&gt; scrollView.maximumZoomScale) scrollView.zoomScale = scrollView.maximumZoomScale; elseif (scrollView.zoomScale&lt; scrollView.minimumZoomScale) scrollView.zoomScale = scrollView.minimumZoomScale;      [selfscrollViewDidZoom:scrollView]; } #pragma mark - other \/\/ \u0434\u0430\u043b\u0435\u0435 \u043f\u0440\u0438\u0432\u0435\u0434\u0435\u043d \u043d\u0430\u0431\u043e\u0440 \u043c\u0435\u0442\u043e\u0434\u043e\u0432 \u0434\u043b\u044f \u043c\u0430\u0441\u0448\u0442\u0430\u0431\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f  CGSizesizeFill(CGSize size, CGSize sizeToFill) { CGSize newSize; if (size.width \/ sizeToFill.width&lt; size.height \/ sizeToFill.height) newSize = CGSizeMake(sizeToFill.width, sizeToFill.width*size.height\/size.width); else newSize = CGSizeMake(sizeToFill.height*size.width\/size.height, sizeToFill.height);  return newSize; }  CGSizesizeFit(CGSize size, CGSize sizeToFit) { float w = size.width\/sizeToFit.width; float h = size.height\/sizeToFit.height; return w &gt; h ? CGSizeMake(sizeToFit.width, size.height\/w) : CGSizeMake(size.width\/h, sizeToFit.height); } CGRectframeFill(CGSize size, CGSize sizeToFill) { CGSize szFill = sizeFill(size, sizeToFill); CGPoint pntFill = CGPointMake(sizeToFill.width\/2.-szFill.width\/2., sizeToFill.height\/2.-szFill.height\/2.); returnCGRectMake(pntFill.x, pntFill.y, szFill.width, szFill.height); }<\/code><\/pre>\n<p>  \u0421\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0439 \u043c\u0435\u0442\u043e\u0434 \u0436\u0438\u0437\u043d\u0435\u043d\u043d\u043e\u0433\u043e \u0446\u0438\u043a\u043b\u0430 ViewController \u2013 \u044d\u0442\u043e viewDidLoad. viewDidLoad \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0445\u043e\u0440\u043e\u0448\u0438\u043c \u043c\u0435\u0441\u0442\u043e\u043c \u0434\u043b\u044f \u043f\u0440\u043e\u0434\u043e\u043b\u0436\u0435\u043d\u0438\u044f \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440\u0430. \u041d\u0430\u043c \u043e\u043d \u043d\u0435 \u043f\u043e\u043d\u0430\u0434\u043e\u0431\u0438\u0442\u0441\u044f \u043f\u043e \u043f\u0440\u0438\u0447\u0438\u043d\u0435 \u0442\u043e\u0433\u043e, \u0447\u0442\u043e \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u0432\u0441\u0435\u0445 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u043e\u0432 \u0434\u0438\u0437\u0430\u0439\u043d\u0430 \u0443\u0436\u0435 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0430. \u041e\u0434\u043d\u0430\u043a\u043e \u0440\u0430\u0437\u043c\u0435\u0440\u044b view \u043d\u0435 \u0437\u0430\u0434\u0430\u043d\u044b, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u0434\u043e\u0431\u0430\u0432\u0438\u043c \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0443 ScrollView \u0432 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u043c \u044d\u0442\u0430\u043f\u0435 \u0436\u0438\u0437\u043d\u0435\u043d\u043d\u043e\u0433\u043e \u0446\u0438\u043a\u043b\u0430 viewWillAppear:<\/p>\n<pre><code class=\"objectivec\">-(void)viewWillAppear:(BOOL)animated {     [superviewWillAppear:animated];     dispatch_async(dispatch_get_main_queue(), ^{         [selfupdateScaleInScrollView:self.scrollView];     });  } <\/code><\/pre>\n<p>  \u0421\u043e\u0437\u0434\u0430\u0434\u0438\u043c \u043c\u0435\u0442\u043e\u0434 \u0434\u043b\u044f \u0432\u044b\u0432\u043e\u0434\u0430 \u043f\u0440\u0435\u0432\u044c\u044e \u0444\u0438\u043b\u044c\u0442\u0440\u043e\u0432:<\/p>\n<pre><code class=\"objectivec\">-(void)makeFilterPreviews {     self.filterPreviews = [[NSMutableArrayalloc] init];          float size = 90 * [UIScreenmainScreen].scale; \u2028                  CGRect cropRect = frameFill(self.image.size,CGSizeMake(size, size));                  UIGraphicsBeginImageContext(CGSizeMake(size, size));         [self.imagedrawInRect:cropRect];         UIImage *cropped = UIGraphicsGetImageFromCurrentImageContext();         UIGraphicsEndImageContext();                 CIImage *ciimg = [[CIImagealloc] initWithImage:cropped]; \u2028                  for (int i = 0; i &lt; [UIImagefilterNames].count; i++)         {                          CIImage *ciFiltered = [ciimg applyFilter:i];             UIImage *filtered = [UIImageimageWithCIImageImproved:ciFiltered];                              [self.filterPreviewsaddObject:filtered]; \u2028                      }       } <\/code><\/pre>\n<p>  \u0438 \u043f\u0440\u043e\u043f\u0438\u0448\u0435\u043c \u0432\u044b\u0437\u043e\u0432 \u044d\u0442\u043e\u0433\u043e \u043c\u0435\u0442\u043e\u0434\u0430 \u0432 loadView<\/p>\n<pre><code class=\"objectivec\">[self makeFilterPreviews]; <\/code><\/pre>\n<p>  <img decoding=\"async\" src=\"https:\/\/habrastorage.org\/files\/e4b\/12c\/83a\/e4b12c83ab5140c488152b898c4ea5ef.PNG\"\/><\/p>\n<p>  \u0417\u0430\u043f\u0443\u0441\u0442\u0438\u043c \u043d\u0430\u0448 \u043f\u0440\u043e\u0435\u043a\u0442. \u041f\u043e\u0441\u043b\u0435 \u0432\u044b\u0431\u043e\u0440\u0430 \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044f \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u0437\u0430\u0432\u0438\u0441\u0430\u0435\u0442 \u043d\u0430 \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u0432\u0440\u0435\u043c\u044f. \u042d\u0442\u043e \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u0438\u0442 \u043f\u043e\u0442\u043e\u043c\u0443, \u0447\u0442\u043e \u043d\u0430 \u043f\u0440\u0438\u043c\u0435\u043d\u0435\u043d\u0438\u0435 \u0444\u0438\u043b\u044c\u0442\u0440\u043e\u0432 \u043a \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044e \u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f \u0432\u0440\u0435\u043c\u044f. \u041f\u043e\u0441\u043b\u0435 \u043f\u0440\u0438\u043c\u0435\u043d\u0435\u043d\u0438\u044f \u0432\u0441\u0435\u0445 \u0444\u0438\u043b\u044c\u0442\u0440\u043e\u0432 \u0437\u0430\u0433\u0440\u0443\u0437\u0438\u0442\u0441\u044f \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440 \u0441 \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0435\u043c \u0438 \u043a\u043e\u043b\u043b\u0435\u043a\u0446\u0438\u044f \u0441 \u0444\u0438\u043b\u044c\u0442\u0440\u0430\u043c\u0438.<\/p>\n<p>  \u0427\u0442\u043e\u0431\u044b \u043e\u0431\u0435\u0441\u043f\u0435\u0447\u0438\u0442\u044c \u043e\u0442\u0437\u044b\u0432\u0447\u0438\u0432\u043e\u0441\u0442\u044c \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u0430, \u0434\u043e\u0431\u0430\u0432\u0438\u043c \u0430\u0441\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u043e\u0441\u0442\u044c \u043f\u0440\u0438 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u0438 \u043c\u0435\u0442\u043e\u0434\u0430. <\/p>\n<pre><code class=\"objectivec\">-(void)makeFilterPreviews {     self.filterPreviews = [[NSMutableArrayalloc] init]; \u2028 \/\/\u0417\u0430\u043f\u043e\u043b\u043d\u0438\u043c \u043c\u0430\u0441\u0441\u0438\u0432 \u043f\u0443\u0441\u0442\u044b\u043c\u0438 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u0430\u043c\u0438 \u0434\u043b\u044f \u043f\u0440\u0435\u0434\u0432\u0430\u0440\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0433\u043e \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044f \u0432 \u043a\u043e\u043b\u043b\u0435\u043a\u0446\u0438\u044e -&gt;     for (long i = 0; i &lt; [UIImagefilterNames].count; i++)     {         [self.filterPreviews addObject:[[UIImage alloc]init]];     }          float size = 90 * [UIScreenmainScreen].scale;               CGRect cropRect = frameFill(self.image.size,CGSizeMake(size, size));          UIGraphicsBeginImageContext(CGSizeMake(size, size));     [self.imagedrawInRect:cropRect];     UIImage *cropped = UIGraphicsGetImageFromCurrentImageContext();     UIGraphicsEndImageContext();          CIImage *ciimg = [[CIImagealloc] initWithImage:cropped]; \/\/\u0441\u043e\u0437\u0434\u0430\u0434\u0438\u043c \u043e\u0447\u0435\u0440\u0435\u0434\u044c \u0434\u043b\u044f \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u043f\u0440\u0435\u0432\u044c\u044e \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044f \u0441 \u043f\u0440\u0438\u043c\u0435\u043d\u0435\u043d\u043d\u044b\u043c \u0444\u0438\u043b\u044c\u0442\u0440\u043e\u043c     NSOperationQueue *queue = [[NSOperationQueuealloc]init];     queue.maxConcurrentOperationCount = 2;          for (int i = 0; i &lt; [UIImagefilterNames].count; i++)     { \u2028         [queueaddOperationWithBlock:^{             CIImage *ciFiltered = [ciimg applyFilter:i];             UIImage *filtered = [UIImageimageWithCIImageImproved:ciFiltered];                          @synchronized (self.filterPreviews) {                 [self.filterPreviewsreplaceObjectAtIndex:i withObject:filtered];                 dispatch_sync(dispatch_get_main_queue(), ^{                     [self.filtersCollectionreloadData];                 });             }         }];     }       } \u2028 \u2028<\/code><\/pre>\n<p>  @synchronized (self.filterPreviews) \u0431\u043b\u043e\u043a\u0438\u0440\u0443\u0435\u0442 \u0440\u0435\u0434\u0430\u043a\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u043c\u0430\u0441\u0441\u0438\u0432\u0430 filterPreviews \u0434\u043b\u044f \u0432\u0441\u0435\u0445 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u043e\u0432, \u043a\u0440\u043e\u043c\u0435 \u0442\u0435\u043a\u0443\u0449\u0435\u0433\u043e.<br \/>  \u0427\u0442\u043e\u0431\u044b \u043a\u043e\u0440\u0440\u0435\u043a\u0442\u043d\u043e \u043e\u0431\u043d\u043e\u0432\u0438\u0442\u044c \u043a\u043e\u043b\u043b\u0435\u043a\u0446\u0438\u044e, \u043d\u0443\u0436\u043d\u043e \u044d\u0442\u043e \u0434\u0435\u043b\u0430\u0442\u044c \u0432 \u043f\u043e\u0442\u043e\u043a\u0435 dispatch_get_main_queue().<\/p>\n<p>  \u041e\u0441\u0442\u0430\u0432\u0448\u0438\u0435\u0441\u044f \u043c\u0435\u0442\u043e\u0434\u044b \u0436\u0438\u0437\u043d\u0435\u043d\u043d\u043e\u0433\u043e \u0446\u0438\u043a\u043b\u0430 ViewController:  <\/p>\n<ul>\n<li> viewDidAppear:(BOOL)animated \u2014 \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u043f\u043e\u0441\u043b\u0435 \u043e\u0442\u0440\u0438\u0441\u043e\u0432\u043a\u0438 \u0432\u0441\u0435\u0445 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u043e\u0432 \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u0430 <\/li>\n<li> viewWillDisappear:(BOOL)animated \u2014 \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u043f\u0435\u0440\u0435\u0434 \u0443\u0434\u0430\u043b\u0435\u043d\u0438\u0435\u043c \u0432\u0441\u0435\u0445 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u043e\u0432 \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u0430 <\/li>\n<li> viewDidDisappear:(BOOL)animated \u2013 \u0432\u044b\u0437\u0432\u0430\u0435\u0442\u0441\u044f \u043f\u043e\u0441\u043b\u0435 \u0443\u0434\u0430\u043b\u0435\u043d\u0438\u044f<\/li>\n<li> viewDidUnload \u2013 \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f, \u043a\u043e\u0433\u0434\u0430 view \u0432\u044b\u0433\u0440\u0443\u0436\u0435\u043d \u0438\u0437 \u043f\u0430\u043c\u044f\u0442\u0438<\/li>\n<\/ul>\n<p>  \u043d\u0430\u043c\u0438 \u043d\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043b\u0438\u0441\u044c.<\/p>\n<p>  \u0422\u0435\u043f\u0435\u0440\u044c \u0441\u043e\u0437\u0434\u0430\u0434\u0438\u043c \u043a\u043d\u043e\u043f\u043a\u0443 Save.<\/p>\n<p>  \u0414\u043e\u0431\u0430\u0432\u0438\u043c Navigation Item <\/p>\n<p>  <img decoding=\"async\" src=\"https:\/\/habrastorage.org\/files\/deb\/514\/10a\/deb51410ac0e4313864dde0dbb01261c.PNG\"\/><\/p>\n<p>  <img decoding=\"async\" src=\"https:\/\/habrastorage.org\/files\/9f0\/fe8\/6e5\/9f0fe86e585e4154b99c1b7ab21a78cb.PNG\"\/><\/p>\n<p>  \u0434\u043e\u0431\u0430\u0432\u0438\u043c \u043a\u043d\u043e\u043f\u043a\u0443 \u043d\u0430 Navigation Item <\/p>\n<p>  <img decoding=\"async\" src=\"https:\/\/habrastorage.org\/files\/7fd\/7a2\/ce5\/7fd7a2ce541841b78d694e991779f634.PNG\"\/><\/p>\n<p>  \u0438 \u043f\u0440\u043e\u043f\u0438\u0448\u0435\u043c \u0432 \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0438 \u043a\u043d\u043e\u043f\u043a\u0438:<\/p>\n<pre><code class=\"objectivec\">- (IBAction)saveBtn:(id)sender {     UIImageWriteToSavedPhotosAlbum(_imageView.image, nil, nil, nil); }<\/code><\/pre>\n<p>  \u0417\u0430\u043f\u0443\u0441\u0442\u0438\u043c \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435, \u0432\u044b\u0431\u0435\u0440\u0435\u043c \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0435 \u0438 \u0444\u0438\u043b\u044c\u0442\u0440. \u041a\u043e\u0433\u0434\u0430 \u0444\u0438\u043b\u044c\u0442\u0440 \u0431\u0443\u0434\u0435\u0442 \u043f\u0440\u0438\u043c\u0435\u043d\u0435\u043d, \u043d\u0430\u0436\u043c\u0435\u043c Save. \u041d\u0430 \u0441\u0438\u043c\u0443\u043b\u044f\u0442\u043e\u0440\u0435 \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043a\u043e\u043c\u0431\u0438\u043d\u0430\u0446\u0438\u044e \u043a\u043b\u0430\u0432\u0438\u0448 cmd+shift+h (\u044d\u0442\u043e \u0442\u043e\u0436\u0435 \u0441\u0430\u043c\u043e\u0435 \u0447\u0442\u043e \u0438 \u043a\u043d\u043e\u043f\u043a\u0430 \u201c\u0414\u043e\u043c\u043e\u0439\u201d \u043d\u0430 iPhone), \u043e\u0442\u043a\u0440\u044b\u0442\u044c \u0413\u0430\u043b\u0435\u0440\u0435\u044e \u2013 \u0438 \u043d\u0430\u0439\u0442\u0438 \u0442\u0430\u043c \u0442\u043e \u0441\u0430\u043c\u043e\u0435 \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0435.<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:\/\/habrahabr.ru\/post\/325352\/\"> https:\/\/habrahabr.ru\/post\/325352\/<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>\u0421\u0435\u0433\u043e\u0434\u043d\u044f \u043c\u044b \u043f\u0440\u0435\u0434\u043b\u0430\u0433\u0430\u0435\u043c \u0447\u0438\u0442\u0430\u0442\u0435\u043b\u044f\u043c \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u043e\u0435 \u0440\u0443\u043a\u043e\u0432\u043e\u0434\u0441\u0442\u0432\u043e \u043f\u043e \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044e \u043f\u0440\u043e\u0441\u0442\u043e\u0433\u043e \u0444\u043e\u0442\u043e\u0440\u0435\u0434\u0430\u043a\u0442\u043e\u0440\u0430 \u043d\u0430 iOS. \u0414\u043b\u044f \u043e\u043f\u044b\u0442\u043d\u044b\u0445 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u043e\u0432 \u0437\u0430\u0434\u0430\u0447\u0430 \u043d\u0435\u0441\u043b\u043e\u0436\u043d\u0430\u044f, \u043d\u043e \u043d\u043e\u0432\u0438\u0447\u043a\u0430\u043c \u043f\u043e\u0434\u043e\u0431\u043d\u044b\u0439 \u043f\u043e\u0448\u0430\u0433\u043e\u0432\u044b\u0439 \u0440\u0430\u0437\u0431\u043e\u0440 \u0432\u0441\u0435\u0433\u043e \u043f\u0440\u043e\u0446\u0435\u0441\u0441\u0430, \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e, \u043e\u043a\u0430\u0436\u0435\u0442\u0441\u044f \u043f\u043e\u043b\u0435\u0437\u0435\u043d. \u041c\u044b \u043e\u0442\u0434\u0430\u043b\u0438 \u043f\u0440\u0435\u0434\u043f\u043e\u0447\u0442\u0435\u043d\u0438\u0435 \u043a\u043b\u0430\u0441\u0441\u0438\u0447\u0435\u0441\u043a\u043e\u0439 \u0441\u0440\u0435\u0434\u0435 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u0434\u043b\u044f \u0432\u044b\u0431\u0440\u0430\u043d\u043d\u043e\u0439 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u043e\u043d\u043d\u043e\u0439 \u0441\u0438\u0441\u0442\u0435\u043c\u044b \u2013 Xcode version 8.2.1. \u0420\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0443 \u0431\u0443\u0434\u0435\u043c \u0432\u0435\u0441\u0442\u0438, \u043e\u043f\u044f\u0442\u044c \u0436\u0435, \u043d\u0430 \u043a\u043b\u0430\u0441\u0441\u0438\u0447\u0435\u0441\u043a\u043e\u043c \u043e\u0431\u044a\u0435\u043a\u0442\u043d\u043e-\u043e\u0440\u0438\u0435\u043d\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u043e\u043c \u044f\u0437\u044b\u043a\u0435 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f Objective-C.<\/p>\n<p>  \u041f\u0440\u0435\u0436\u0434\u0435 \u0447\u0435\u043c \u043f\u0440\u0438\u0441\u0442\u0443\u043f\u0430\u0442\u044c \u043a \u0441\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u043e \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0435, \u043f\u0440\u0435\u0434\u043b\u0430\u0433\u0430\u0435\u043c \u0441\u043d\u0430\u0447\u0430\u043b\u0430 \u0440\u0430\u0437\u0431\u0438\u0442\u044c \u0437\u0430\u0434\u0430\u0447\u0443 \u043d\u0430 \u043f\u043e\u0434\u0437\u0430\u0434\u0430\u0447\u0438. <\/p>\n<ol>\n<li>\u0417\u0430\u0433\u0440\u0443\u0437\u0438\u0442\u044c \u0444\u043e\u0442\u043e\u0433\u0440\u0430\u0444\u0438\u044e \u0438\u0437 \u0433\u0430\u043b\u0435\u0440\u0435\u0438<\/li>\n<li>\u0421\u043e\u0437\u0434\u0430\u0442\u044c \u043a\u043e\u043b\u043b\u0435\u043a\u0446\u0438\u044e \u0441 \u0444\u0438\u043b\u044c\u0442\u0440\u0430\u043c\u0438<\/li>\n<li>\u0420\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u0442\u044c \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u043f\u0440\u0438\u043c\u0435\u043d\u044f\u0442\u044c \u043b\u044e\u0431\u043e\u0439 \u0438\u0437 \u0444\u0438\u043b\u044c\u0442\u0440\u043e\u0432 \u043d\u0430 \u0432\u044b\u0431\u0440\u0430\u043d\u043d\u0443\u044e \u043d\u0430\u043c\u0438 \u0444\u043e\u0442\u043e\u0433\u0440\u0430\u0444\u0438\u044e<\/li>\n<li> \u0421\u043e\u0445\u0440\u0430\u043d\u0438\u0442\u044c \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u0432 \u0433\u0430\u043b\u0435\u0440\u0435\u044e.<\/li>\n<\/ol>\n<p>  <\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[],"tags":[],"class_list":["post-284254","post","type-post","status-publish","format-standard","hentry"],"_links":{"self":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/284254","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=284254"}],"version-history":[{"count":0,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/284254\/revisions"}],"wp:attachment":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=284254"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=284254"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=284254"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}