{"id":2748,"date":"2017-07-31T07:15:02","date_gmt":"2017-07-31T07:15:02","guid":{"rendered":"https:\/\/intelligentbee.com\/blog\/?p=2748"},"modified":"2024-12-13T08:15:29","modified_gmt":"2024-12-13T08:15:29","slug":"tutorial-building-travel-photo-sharing-ios-app","status":"publish","type":"post","link":"https:\/\/intelligentbee.com\/blog\/tutorial-building-travel-photo-sharing-ios-app\/","title":{"rendered":"Building a Travel Photo Sharing iOS\u00a0App"},"content":{"rendered":"<p>Hello! I want to show you how to build a relative simple photo sharing app with a twist: your images will be placed on a map background of your current location. You will also be able to add a short message and your name, to end up with an image looking like this (so you can brag to your friends with what you visited in the awesome vacation you have):<\/p>\n<p><img decoding=\"async\" class=\"alignnone size-large wp-image-2749\" src=\"https:\/\/intelligentbee.com\/blog\/wp-content\/uploads\/2017\/07\/1-2Z4Yx76tQdCBL7Xr-m0boQ-769x1024.jpeg\" alt=\"\" width=\"525\" height=\"699\" srcset=\"https:\/\/intelligentbee.com\/blog\/wp-content\/uploads\/2017\/07\/1-2Z4Yx76tQdCBL7Xr-m0boQ-769x1024.jpeg 769w, https:\/\/intelligentbee.com\/blog\/wp-content\/uploads\/2017\/07\/1-2Z4Yx76tQdCBL7Xr-m0boQ-225x300.jpeg 225w, https:\/\/intelligentbee.com\/blog\/wp-content\/uploads\/2017\/07\/1-2Z4Yx76tQdCBL7Xr-m0boQ-768x1022.jpeg 768w, https:\/\/intelligentbee.com\/blog\/wp-content\/uploads\/2017\/07\/1-2Z4Yx76tQdCBL7Xr-m0boQ.jpeg 800w\" sizes=\"(max-width: 525px) 100vw, 525px\" \/><\/p>\n<p>To follow this tutorial you need an Apple computer with xCode installed and an Apple developer account.<\/p>\n<div id=\"ez-toc-container\" class=\"ez-toc-v2_0_68_1 counter-hierarchy ez-toc-counter ez-toc-grey ez-toc-container-direction\">\n<div class=\"ez-toc-title-container\">\n<p class=\"ez-toc-title \" >Table of Contents<\/p>\n<span class=\"ez-toc-title-toggle\"><a href=\"#\" class=\"ez-toc-pull-right ez-toc-btn ez-toc-btn-xs ez-toc-btn-default ez-toc-toggle\" aria-label=\"Toggle Table of Content\"><span class=\"ez-toc-js-icon-con\"><span class=\"\"><span class=\"eztoc-hide\" style=\"display:none;\">Toggle<\/span><span class=\"ez-toc-icon-toggle-span\"><svg style=\"fill: #999;color:#999\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\" class=\"list-377408\" width=\"20px\" height=\"20px\" viewBox=\"0 0 24 24\" fill=\"none\"><path d=\"M6 6H4v2h2V6zm14 0H8v2h12V6zM4 11h2v2H4v-2zm16 0H8v2h12v-2zM4 16h2v2H4v-2zm16 0H8v2h12v-2z\" fill=\"currentColor\"><\/path><\/svg><svg style=\"fill: #999;color:#999\" class=\"arrow-unsorted-368013\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"10px\" height=\"10px\" viewBox=\"0 0 24 24\" version=\"1.2\" baseProfile=\"tiny\"><path d=\"M18.2 9.3l-6.2-6.3-6.2 6.3c-.2.2-.3.4-.3.7s.1.5.3.7c.2.2.4.3.7.3h11c.3 0 .5-.1.7-.3.2-.2.3-.5.3-.7s-.1-.5-.3-.7zM5.8 14.7l6.2 6.3 6.2-6.3c.2-.2.3-.5.3-.7s-.1-.5-.3-.7c-.2-.2-.4-.3-.7-.3h-11c-.3 0-.5.1-.7.3-.2.2-.3.5-.3.7s.1.5.3.7z\"\/><\/svg><\/span><\/span><\/span><\/a><\/span><\/div>\n<nav><ul class='ez-toc-list ez-toc-list-level-1 ' ><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-1\" href=\"https:\/\/intelligentbee.com\/blog\/tutorial-building-travel-photo-sharing-ios-app\/#Create_the_Project\" title=\"Create the\u00a0Project\">Create the\u00a0Project<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-2\" href=\"https:\/\/intelligentbee.com\/blog\/tutorial-building-travel-photo-sharing-ios-app\/#Building_the_Interface\" title=\"Building the Interface\">Building the Interface<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-3\" href=\"https:\/\/intelligentbee.com\/blog\/tutorial-building-travel-photo-sharing-ios-app\/#Taking_a_Photo\" title=\"Taking a\u00a0Photo\">Taking a\u00a0Photo<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-4\" href=\"https:\/\/intelligentbee.com\/blog\/tutorial-building-travel-photo-sharing-ios-app\/#Getting_Current_User_Location\" title=\"Getting Current User\u00a0Location\">Getting Current User\u00a0Location<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-5\" href=\"https:\/\/intelligentbee.com\/blog\/tutorial-building-travel-photo-sharing-ios-app\/#Generate_the_Map_Image\" title=\"Generate the Map\u00a0Image\">Generate the Map\u00a0Image<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-6\" href=\"https:\/\/intelligentbee.com\/blog\/tutorial-building-travel-photo-sharing-ios-app\/#Building_the_Final_Image\" title=\"Building the Final\u00a0Image\">Building the Final\u00a0Image<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-7\" href=\"https:\/\/intelligentbee.com\/blog\/tutorial-building-travel-photo-sharing-ios-app\/#Sharing_the_Final_Image\" title=\"Sharing the Final\u00a0Image\">Sharing the Final\u00a0Image<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-8\" href=\"https:\/\/intelligentbee.com\/blog\/tutorial-building-travel-photo-sharing-ios-app\/#Final_Touches\" title=\"Final Touches\">Final Touches<\/a><\/li><\/ul><\/nav><\/div>\n<h2><span class=\"ez-toc-section\" id=\"Create_the_Project\"><\/span>Create the\u00a0Project<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>Open xCode and create a new project named <strong>PicTravel<\/strong>. Choose the <strong>Single View Application<\/strong> template:<\/p>\n<p><img decoding=\"async\" class=\"alignnone size-full wp-image-2753\" src=\"https:\/\/intelligentbee.com\/blog\/wp-content\/uploads\/2017\/07\/1-H4CDkqsRzcZVq1E8wjJqrA.png\" alt=\"\" width=\"730\" height=\"521\" srcset=\"https:\/\/intelligentbee.com\/blog\/wp-content\/uploads\/2017\/07\/1-H4CDkqsRzcZVq1E8wjJqrA.png 730w, https:\/\/intelligentbee.com\/blog\/wp-content\/uploads\/2017\/07\/1-H4CDkqsRzcZVq1E8wjJqrA-300x214.png 300w\" sizes=\"(max-width: 730px) 100vw, 730px\" \/><\/p>\n<p>Give the project a name, we chose <code>PicTravel<\/code> but you ca choose what other name you like. Also fill in the organization name and the organization identifier for your project:<\/p>\n<p><img decoding=\"async\" class=\"alignnone size-full wp-image-2754\" src=\"https:\/\/intelligentbee.com\/blog\/wp-content\/uploads\/2017\/07\/1-P1vrlpx72uU6kEbwrTwSmQ.png\" alt=\"\" width=\"728\" height=\"524\" srcset=\"https:\/\/intelligentbee.com\/blog\/wp-content\/uploads\/2017\/07\/1-P1vrlpx72uU6kEbwrTwSmQ.png 728w, https:\/\/intelligentbee.com\/blog\/wp-content\/uploads\/2017\/07\/1-P1vrlpx72uU6kEbwrTwSmQ-300x216.png 300w\" sizes=\"(max-width: 728px) 100vw, 728px\" \/><\/p>\n<p>The last step is to save the newly created project in your <code>Developer<\/code> folder.<\/p>\n<h2><span class=\"ez-toc-section\" id=\"Building_the_Interface\"><\/span>Building the Interface<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>From the left panel, open the <code>Main.storyboard<\/code>. This is where we will build our app interface.<\/p>\n<p><img decoding=\"async\" class=\"alignnone size-full wp-image-2756\" src=\"https:\/\/intelligentbee.com\/blog\/wp-content\/uploads\/2017\/07\/1-H8RCa-43H4I1ZX6RIXVy7w.png\" alt=\"\" width=\"800\" height=\"500\" srcset=\"https:\/\/intelligentbee.com\/blog\/wp-content\/uploads\/2017\/07\/1-H8RCa-43H4I1ZX6RIXVy7w.png 800w, https:\/\/intelligentbee.com\/blog\/wp-content\/uploads\/2017\/07\/1-H8RCa-43H4I1ZX6RIXVy7w-300x188.png 300w, https:\/\/intelligentbee.com\/blog\/wp-content\/uploads\/2017\/07\/1-H8RCa-43H4I1ZX6RIXVy7w-768x480.png 768w\" sizes=\"(max-width: 800px) 100vw, 800px\" \/><\/p>\n<p>From the right panel, the bottom part, drag an ImageView and place it in the center of the scene. Resize it so it covers everything (snap it to the blue lines that appear).<\/p>\n<p><img decoding=\"async\" class=\"alignnone size-full wp-image-2757\" src=\"https:\/\/intelligentbee.com\/blog\/wp-content\/uploads\/2017\/07\/1-SfQTp47nVMi6O8M3bPb7nw.png\" alt=\"\" width=\"800\" height=\"500\" srcset=\"https:\/\/intelligentbee.com\/blog\/wp-content\/uploads\/2017\/07\/1-SfQTp47nVMi6O8M3bPb7nw.png 800w, https:\/\/intelligentbee.com\/blog\/wp-content\/uploads\/2017\/07\/1-SfQTp47nVMi6O8M3bPb7nw-300x188.png 300w, https:\/\/intelligentbee.com\/blog\/wp-content\/uploads\/2017\/07\/1-SfQTp47nVMi6O8M3bPb7nw-768x480.png 768w\" sizes=\"(max-width: 800px) 100vw, 800px\" \/><\/p>\n<p>Pin the ImageView to the scene margins using the constraints dialog like you see in the image below:<\/p>\n<p><img decoding=\"async\" class=\"alignnone size-full wp-image-2758\" src=\"https:\/\/intelligentbee.com\/blog\/wp-content\/uploads\/2017\/07\/1-nfgqEwER6r6HE3b5x0rqyg.png\" alt=\"\" width=\"800\" height=\"500\" srcset=\"https:\/\/intelligentbee.com\/blog\/wp-content\/uploads\/2017\/07\/1-nfgqEwER6r6HE3b5x0rqyg.png 800w, https:\/\/intelligentbee.com\/blog\/wp-content\/uploads\/2017\/07\/1-nfgqEwER6r6HE3b5x0rqyg-300x188.png 300w, https:\/\/intelligentbee.com\/blog\/wp-content\/uploads\/2017\/07\/1-nfgqEwER6r6HE3b5x0rqyg-768x480.png 768w\" sizes=\"(max-width: 800px) 100vw, 800px\" \/><\/p>\n<p>We will use this to put a background image for our app\u2019s main screen. Download the background image from <a href=\"https:\/\/github.com\/intelligentbee\/PicTravel\/tree\/master\/PicTravel\/Assets.xcassets\/Background.imageset\" target=\"_blank\" rel=\"noopener\">here<\/a> then open the <code>Assets.xcassets<\/code> item from the left panel, click on the \u201c+\u201d button from the bottom and add a new image set named <code>Background<\/code>.<\/p>\n<p><img decoding=\"async\" class=\"alignnone size-full wp-image-2760\" src=\"https:\/\/intelligentbee.com\/blog\/wp-content\/uploads\/2017\/07\/1-gXcSrPoVQRudfS9AgmWgLw.png\" alt=\"\" width=\"800\" height=\"500\" srcset=\"https:\/\/intelligentbee.com\/blog\/wp-content\/uploads\/2017\/07\/1-gXcSrPoVQRudfS9AgmWgLw.png 800w, https:\/\/intelligentbee.com\/blog\/wp-content\/uploads\/2017\/07\/1-gXcSrPoVQRudfS9AgmWgLw-300x188.png 300w, https:\/\/intelligentbee.com\/blog\/wp-content\/uploads\/2017\/07\/1-gXcSrPoVQRudfS9AgmWgLw-768x480.png 768w\" sizes=\"(max-width: 800px) 100vw, 800px\" \/><\/p>\n<p>Drag the downloaded image to the \u201c1x\u201d placeholder to end up with something like this (we will not use the \u201c2x\u201d and \u201c3x\u201d placeholder for this tutorial, but you can add bigger resolution images to it if you want).<\/p>\n<p><img decoding=\"async\" class=\"alignnone size-full wp-image-2761\" src=\"https:\/\/intelligentbee.com\/blog\/wp-content\/uploads\/2017\/07\/1-4tcfoHb3Z_I9ACsOBRb9Fw.png\" alt=\"\" width=\"800\" height=\"500\" srcset=\"https:\/\/intelligentbee.com\/blog\/wp-content\/uploads\/2017\/07\/1-4tcfoHb3Z_I9ACsOBRb9Fw.png 800w, https:\/\/intelligentbee.com\/blog\/wp-content\/uploads\/2017\/07\/1-4tcfoHb3Z_I9ACsOBRb9Fw-300x188.png 300w, https:\/\/intelligentbee.com\/blog\/wp-content\/uploads\/2017\/07\/1-4tcfoHb3Z_I9ACsOBRb9Fw-768x480.png 768w\" sizes=\"(max-width: 800px) 100vw, 800px\" \/><\/p>\n<p>Now, back to the <code>Main.storyboard<\/code>, select the <code>ImageView<\/code> and, from the Attributes Inspector, select the <code>Background<\/code> image and set the Content Mode to Aspect Fill.<\/p>\n<p><img decoding=\"async\" class=\"alignnone size-full wp-image-2762\" src=\"https:\/\/intelligentbee.com\/blog\/wp-content\/uploads\/2017\/07\/1-hYS3la_Lm_NR8moDZXMjFg.png\" alt=\"\" width=\"800\" height=\"500\" srcset=\"https:\/\/intelligentbee.com\/blog\/wp-content\/uploads\/2017\/07\/1-hYS3la_Lm_NR8moDZXMjFg.png 800w, https:\/\/intelligentbee.com\/blog\/wp-content\/uploads\/2017\/07\/1-hYS3la_Lm_NR8moDZXMjFg-300x188.png 300w, https:\/\/intelligentbee.com\/blog\/wp-content\/uploads\/2017\/07\/1-hYS3la_Lm_NR8moDZXMjFg-768x480.png 768w\" sizes=\"(max-width: 800px) 100vw, 800px\" \/><\/p>\n<p class=\"graf graf--p\">It\u2019s time to add a new image to our assets that we will use for the take a photo button we are about to add. Download the image from <a class=\"markup--anchor markup--p-anchor\" href=\"https:\/\/github.com\/intelligentbee\/PicTravel\/tree\/master\/PicTravel\/Assets.xcassets\/Button.imageset\" target=\"_blank\" rel=\"noopener\" data-href=\"https:\/\/github.com\/intelligentbee\/PicTravel\/tree\/master\/PicTravel\/Assets.xcassets\/Button.imageset\">here<\/a>, create a new Image Set named <code class=\"markup--code markup--p-code\">Button<\/code> in the Assets.xcassets and drag the image into the <code class=\"markup--code markup--p-code\">1x<\/code> placeholder like we did earlier with the background.<\/p>\n<p class=\"graf graf--p\">Next, in the <code class=\"markup--code markup--p-code\">Main.storybord<\/code>, drag a button to the center of the scene. Set it\u2019s Type to <code class=\"markup--code markup--p-code\">Custom<\/code>, clear the Title and set the Background to the <code class=\"markup--code markup--p-code\">Button<\/code> image we just created. From the Size Inspector, set the button with and height to <code class=\"markup--code markup--p-code\">115<\/code>.<\/p>\n<p class=\"graf graf--p\">Add two new constraints for the button\u2019s with and heigh (115 each), then, from the Alignment Constriants, align the button horizontally and vertically in the container.<\/p>\n<p><img decoding=\"async\" class=\"alignnone size-full wp-image-2765\" src=\"https:\/\/intelligentbee.com\/blog\/wp-content\/uploads\/2017\/07\/1-FxSRCPTzLbZZCSATXuQxng.png\" alt=\"\" width=\"800\" height=\"500\" srcset=\"https:\/\/intelligentbee.com\/blog\/wp-content\/uploads\/2017\/07\/1-FxSRCPTzLbZZCSATXuQxng.png 800w, https:\/\/intelligentbee.com\/blog\/wp-content\/uploads\/2017\/07\/1-FxSRCPTzLbZZCSATXuQxng-300x188.png 300w, https:\/\/intelligentbee.com\/blog\/wp-content\/uploads\/2017\/07\/1-FxSRCPTzLbZZCSATXuQxng-768x480.png 768w\" sizes=\"(max-width: 800px) 100vw, 800px\" \/><\/p>\n<p class=\"graf graf--p\">Now let\u2019s add two text fields for the user\u2019s name and message. Place them like in the image below, with the constraints listed below. Don\u2019t forget the blue guides that make the placement easier for you. To create constrains between two elements you can Ctrl+drag from one to another and select the type of constraint you want from the popup that appears.<\/p>\n<p class=\"graf graf--p\">For the message text field:<\/p>\n<ul class=\"postList\">\n<li class=\"graf graf--li\">Top Space to the name text field: <code class=\"markup--code markup--li-code\">15<\/code><\/li>\n<li class=\"graf graf--li\">Bottom Space to the button: <code class=\"markup--code markup--li-code\">15<\/code><\/li>\n<li class=\"graf graf--li\">Width &lt;= <code class=\"markup--code markup--li-code\">500<\/code><\/li>\n<li class=\"graf graf--li\">Align Center X to superview<\/li>\n<li class=\"graf graf--li\">Trailing Space to superview: <code class=\"markup--code markup--li-code\">0<\/code> with a Priority of <code class=\"markup--code markup--li-code\">900<\/code> &#8211; that\u2019s very important as it will keep the text field pinned to the margin on iPhones but on bigger devices the width constraint will be stronger so it will not grow larger than 500.<\/li>\n<li class=\"graf graf--li\">Leading Space to superview: <code class=\"markup--code markup--li-code\">0<\/code> with a Priority of <code class=\"markup--code markup--li-code\">900<\/code><\/li>\n<\/ul>\n<p class=\"graf graf--p\">For the name field:<\/p>\n<ul class=\"postList\">\n<li class=\"graf graf--li\">Bottom Space to the message text field: <code class=\"markup--code markup--li-code\">15<\/code><\/li>\n<li class=\"graf graf--li\">Width &lt;= <code class=\"markup--code markup--li-code\">500<\/code><\/li>\n<li class=\"graf graf--li\">Align Center X to superview<\/li>\n<li class=\"graf graf--li\">Trailing Space to superview: <code class=\"markup--code markup--li-code\">0<\/code> with a Priority of <code class=\"markup--code markup--li-code\">900<\/code><\/li>\n<li class=\"graf graf--li\">Leading Space to superview: <code class=\"markup--code markup--li-code\">0<\/code> with a Priority of <code class=\"markup--code markup--li-code\">900<\/code><\/li>\n<\/ul>\n<p class=\"graf graf--p\">Set the placeholders for each of the text fields to \u201c<em class=\"markup--em markup--p-em\">Enter Your Name<\/em>\u201d and \u201c<em class=\"markup--em markup--p-em\">Add a Short Message<\/em>\u201d so the user knows what to do. Set the Font to <code class=\"markup--code markup--p-code\">Noteworthy Light<\/code> with a size of <code class=\"markup--code markup--p-code\">17<\/code> for both.<\/p>\n<p class=\"graf graf--p\">Also, for the name field set the Capitalization to <code class=\"markup--code markup--p-code\">Words<\/code>, Correction and SpellChecking, both to <code class=\"markup--code markup--p-code\">No<\/code>. For the message field set the Capitalization to <code class=\"markup--code markup--p-code\">Sentences<\/code>.<\/p>\n<p class=\"graf graf--p\">Here\u2019s the result:<\/p>\n<p><img decoding=\"async\" class=\"alignnone size-full wp-image-2766\" src=\"https:\/\/intelligentbee.com\/blog\/wp-content\/uploads\/2017\/07\/1-ajt1Ye76cXZsh-oQ_ix2gQ.png\" alt=\"\" width=\"800\" height=\"500\" srcset=\"https:\/\/intelligentbee.com\/blog\/wp-content\/uploads\/2017\/07\/1-ajt1Ye76cXZsh-oQ_ix2gQ.png 800w, https:\/\/intelligentbee.com\/blog\/wp-content\/uploads\/2017\/07\/1-ajt1Ye76cXZsh-oQ_ix2gQ-300x188.png 300w, https:\/\/intelligentbee.com\/blog\/wp-content\/uploads\/2017\/07\/1-ajt1Ye76cXZsh-oQ_ix2gQ-768x480.png 768w\" sizes=\"(max-width: 800px) 100vw, 800px\" \/><\/p>\n<p class=\"graf graf--p\">And here\u2019s how it looks on an iPad (you can use the bottom bar under the scene to select on what device you want to preview the interface):<\/p>\n<p><img decoding=\"async\" class=\"alignnone size-full wp-image-2767\" src=\"https:\/\/intelligentbee.com\/blog\/wp-content\/uploads\/2017\/07\/1-mlrzZXHUlXp7YoP-johPnw.png\" alt=\"\" width=\"800\" height=\"500\" srcset=\"https:\/\/intelligentbee.com\/blog\/wp-content\/uploads\/2017\/07\/1-mlrzZXHUlXp7YoP-johPnw.png 800w, https:\/\/intelligentbee.com\/blog\/wp-content\/uploads\/2017\/07\/1-mlrzZXHUlXp7YoP-johPnw-300x188.png 300w, https:\/\/intelligentbee.com\/blog\/wp-content\/uploads\/2017\/07\/1-mlrzZXHUlXp7YoP-johPnw-768x480.png 768w\" sizes=\"(max-width: 800px) 100vw, 800px\" \/><\/p>\n<p class=\"graf graf--p\">There are two more small elements to add and our main screen will be finished.<\/p>\n<p class=\"graf graf--p\">Add a label at the bottom with the following text: \u201c<em class=\"markup--em markup--p-em\">Share your travel experiences instantly with your friends &amp; family!<\/em>\u201d. Set it\u2019s <strong class=\"markup--strong markup--p-strong\">Font<\/strong> to <code class=\"markup--code markup--p-code\">Noteworthly Light 17<\/code>, <strong class=\"markup--strong markup--p-strong\">Alignment<\/strong> to <code class=\"markup--code markup--p-code\">center<\/code>, <strong class=\"markup--strong markup--p-strong\">Color<\/strong> to <code class=\"markup--code markup--p-code\">#5E7A96<\/code> and <strong class=\"markup--strong markup--p-strong\">Lines<\/strong> to <code class=\"markup--code markup--p-code\">0<\/code>. Use the following constrains:<\/p>\n<ul class=\"postList\">\n<li class=\"graf graf--li\"><strong class=\"markup--strong markup--li-strong\">Trailing Space<\/strong> to superview\u2019s margins: <code class=\"markup--code markup--li-code\">0<\/code><\/li>\n<li class=\"graf graf--li\"><strong class=\"markup--strong markup--li-strong\">Leading Space<\/strong> to superview\u2019s margins: <code class=\"markup--code markup--li-code\">0<\/code><\/li>\n<li class=\"graf graf--li\"><strong class=\"markup--strong markup--li-strong\">Bottom Space<\/strong> to Bottom Layout: <code class=\"markup--code markup--li-code\">20<\/code><\/li>\n<li class=\"graf graf--li\"><strong class=\"markup--strong markup--li-strong\">Height<\/strong>: <code class=\"markup--code markup--li-code\">64<\/code><\/li>\n<\/ul>\n<p class=\"graf graf--p\">Finally, add a new view at the top, having a white background with a opacity of 60%. Constrains used are:<\/p>\n<ul class=\"postList\">\n<li class=\"graf graf--li\"><strong class=\"markup--strong markup--li-strong\">Trailing Space<\/strong> to superview: <code class=\"markup--code markup--li-code\">0<\/code><\/li>\n<li class=\"graf graf--li\"><strong class=\"markup--strong markup--li-strong\">Leading Space<\/strong> to superview: <code class=\"markup--code markup--li-code\">0<\/code><\/li>\n<li class=\"graf graf--li\"><strong class=\"markup--strong markup--li-strong\">Bottom Space<\/strong> to Top Layout: <code class=\"markup--code markup--li-code\">20<\/code><\/li>\n<li class=\"graf graf--li\"><strong class=\"markup--strong markup--li-strong\">Height<\/strong>: <code class=\"markup--code markup--li-code\">20<\/code><\/li>\n<\/ul>\n<p class=\"graf graf--p\">Here is the final design:<\/p>\n<p><img decoding=\"async\" class=\"alignnone size-full wp-image-2768\" src=\"https:\/\/intelligentbee.com\/blog\/wp-content\/uploads\/2017\/07\/1-fFoulmQawN2yMLW4NZeqPw.png\" alt=\"\" width=\"800\" height=\"500\" srcset=\"https:\/\/intelligentbee.com\/blog\/wp-content\/uploads\/2017\/07\/1-fFoulmQawN2yMLW4NZeqPw.png 800w, https:\/\/intelligentbee.com\/blog\/wp-content\/uploads\/2017\/07\/1-fFoulmQawN2yMLW4NZeqPw-300x188.png 300w, https:\/\/intelligentbee.com\/blog\/wp-content\/uploads\/2017\/07\/1-fFoulmQawN2yMLW4NZeqPw-768x480.png 768w\" sizes=\"(max-width: 800px) 100vw, 800px\" \/><\/p>\n<p class=\"graf graf--p\">We will use this screen to get the user\u2019s name and message and open the camera or photo library to take a photo. But after we gel all we need from the user, we need a new screen to show the final image and let him share it. So let\u2019s add a new screen to our app.<\/p>\n<p class=\"graf graf--p\">From the Object Library, drag a new View Controller near the first one:<\/p>\n<p><img decoding=\"async\" class=\"alignnone size-full wp-image-2769\" src=\"https:\/\/intelligentbee.com\/blog\/wp-content\/uploads\/2017\/07\/1-PkQsWqq4MeG4RX0MqaFSCw.png\" alt=\"\" width=\"800\" height=\"500\" srcset=\"https:\/\/intelligentbee.com\/blog\/wp-content\/uploads\/2017\/07\/1-PkQsWqq4MeG4RX0MqaFSCw.png 800w, https:\/\/intelligentbee.com\/blog\/wp-content\/uploads\/2017\/07\/1-PkQsWqq4MeG4RX0MqaFSCw-300x188.png 300w, https:\/\/intelligentbee.com\/blog\/wp-content\/uploads\/2017\/07\/1-PkQsWqq4MeG4RX0MqaFSCw-768x480.png 768w\" sizes=\"(max-width: 800px) 100vw, 800px\" \/><\/p>\n<p class=\"graf graf--p\">Set the background for the view of this new View Controller to <code class=\"markup--code markup--p-code\">#ACE0F6<\/code>.<\/p>\n<p class=\"graf graf--p\">Next, add two buttons like in the image below. Type is <code class=\"markup--code markup--p-code\">custom<\/code>, background color is <code class=\"markup--code markup--p-code\">#EE4205<\/code>, font <code class=\"markup--code markup--p-code\">Noteworthy Light 17<\/code>. Height <code class=\"markup--code markup--p-code\">40<\/code>, width <code class=\"markup--code markup--p-code\">70<\/code> and <code class=\"markup--code markup--p-code\">110<\/code>. They are pinned to the bottom layout <code class=\"markup--code markup--p-code\">+ 20<\/code>, left or right of the container and also have constraints on with and height.<\/p>\n<p><img decoding=\"async\" class=\"alignnone size-full wp-image-2770\" src=\"https:\/\/intelligentbee.com\/blog\/wp-content\/uploads\/2017\/07\/1-WDQrkQXtHsLKE3ctDQXGvA.png\" alt=\"\" width=\"800\" height=\"499\" srcset=\"https:\/\/intelligentbee.com\/blog\/wp-content\/uploads\/2017\/07\/1-WDQrkQXtHsLKE3ctDQXGvA.png 800w, https:\/\/intelligentbee.com\/blog\/wp-content\/uploads\/2017\/07\/1-WDQrkQXtHsLKE3ctDQXGvA-300x187.png 300w, https:\/\/intelligentbee.com\/blog\/wp-content\/uploads\/2017\/07\/1-WDQrkQXtHsLKE3ctDQXGvA-768x479.png 768w\" sizes=\"(max-width: 800px) 100vw, 800px\" \/><\/p>\n<p class=\"graf graf--p\">At the top, add a label to show the current status of the app to the user. Pin it to the top, left and right margins using constrains with a height of <code class=\"markup--code markup--p-code\">40<\/code>. Set the font to <code class=\"markup--code markup--p-code\">Noteworthy Light 19<\/code> and color to <code class=\"markup--code markup--p-code\">#EE4205<\/code>. The initial text will be \u201c<em class=\"markup--em markup--p-em\">Generating your image\u2026<\/em>\u201d center aligned.<\/p>\n<p><img decoding=\"async\" class=\"alignnone size-full wp-image-2771\" src=\"https:\/\/intelligentbee.com\/blog\/wp-content\/uploads\/2017\/07\/1-pRw0BbY4KaMlrf2uzRt-JQ.png\" alt=\"\" width=\"800\" height=\"500\" srcset=\"https:\/\/intelligentbee.com\/blog\/wp-content\/uploads\/2017\/07\/1-pRw0BbY4KaMlrf2uzRt-JQ.png 800w, https:\/\/intelligentbee.com\/blog\/wp-content\/uploads\/2017\/07\/1-pRw0BbY4KaMlrf2uzRt-JQ-300x188.png 300w, https:\/\/intelligentbee.com\/blog\/wp-content\/uploads\/2017\/07\/1-pRw0BbY4KaMlrf2uzRt-JQ-768x480.png 768w\" sizes=\"(max-width: 800px) 100vw, 800px\" \/><\/p>\n<p class=\"graf graf--p\">To show the generated image we need an Image View. Drag it to the center of the second screen and create the following constraints for it:<\/p>\n<ul class=\"postList\">\n<li class=\"graf graf--li\"><strong class=\"markup--strong markup--li-strong\">Top Space<\/strong> to \u201c<em class=\"markup--em markup--li-em\">Generating your image\u2026<\/em>\u201d label: <code class=\"markup--code markup--li-code\">8<\/code><\/li>\n<li class=\"graf graf--li\"><strong class=\"markup--strong markup--li-strong\">Bottom Space<\/strong> to \u201c<em class=\"markup--em markup--li-em\">Share Image!<\/em>\u201d button: <code class=\"markup--code markup--li-code\">8<\/code><\/li>\n<li class=\"graf graf--li\"><strong class=\"markup--strong markup--li-strong\">Leading Space<\/strong> to superview margin: <code class=\"markup--code markup--li-code\">0<\/code><\/li>\n<li class=\"graf graf--li\"><strong class=\"markup--strong markup--li-strong\">Trailing Space<\/strong> to superview margin: <code class=\"markup--code markup--li-code\">0<\/code><\/li>\n<\/ul>\n<p class=\"graf graf--p\">Also set it\u2019s <strong class=\"markup--strong markup--p-strong\">Content Mode<\/strong> to <code class=\"markup--code markup--p-code\">Aspect Fit<\/code><\/p>\n<p><img decoding=\"async\" class=\"alignnone size-full wp-image-2772\" src=\"https:\/\/intelligentbee.com\/blog\/wp-content\/uploads\/2017\/07\/1-yBe1phZfs9do1m4O95xOMQ.png\" alt=\"\" width=\"800\" height=\"500\" srcset=\"https:\/\/intelligentbee.com\/blog\/wp-content\/uploads\/2017\/07\/1-yBe1phZfs9do1m4O95xOMQ.png 800w, https:\/\/intelligentbee.com\/blog\/wp-content\/uploads\/2017\/07\/1-yBe1phZfs9do1m4O95xOMQ-300x188.png 300w, https:\/\/intelligentbee.com\/blog\/wp-content\/uploads\/2017\/07\/1-yBe1phZfs9do1m4O95xOMQ-768x480.png 768w\" sizes=\"(max-width: 800px) 100vw, 800px\" \/><\/p>\n<p class=\"graf graf--p\">The last piece of the puzzle is an <strong class=\"markup--strong markup--p-strong\">Activity Indicator View<\/strong> that we will use to visually inform the user that something happens behind the scenes (final image generation) and he has to wait for a few seconds.<\/p>\n<p class=\"graf graf--p\">Drag it from the Object Library and place it in the middle of the screen. Add constraints to center it horizontally and vertically in the container and set its <strong class=\"markup--strong markup--p-strong\">Behavior<\/strong> to <code class=\"markup--code markup--p-code\">Animating<\/code> and <code class=\"markup--code markup--p-code\">Hides When Stopped<\/code>.<\/p>\n<p><img decoding=\"async\" class=\"alignnone size-full wp-image-2773\" src=\"https:\/\/intelligentbee.com\/blog\/wp-content\/uploads\/2017\/07\/1-N_PgGXQSnBvpu0rUkwZmDA.png\" alt=\"\" width=\"800\" height=\"500\" srcset=\"https:\/\/intelligentbee.com\/blog\/wp-content\/uploads\/2017\/07\/1-N_PgGXQSnBvpu0rUkwZmDA.png 800w, https:\/\/intelligentbee.com\/blog\/wp-content\/uploads\/2017\/07\/1-N_PgGXQSnBvpu0rUkwZmDA-300x188.png 300w, https:\/\/intelligentbee.com\/blog\/wp-content\/uploads\/2017\/07\/1-N_PgGXQSnBvpu0rUkwZmDA-768x480.png 768w\" sizes=\"(max-width: 800px) 100vw, 800px\" \/><\/p>\n<p class=\"graf graf--p\">That\u2019s it, our app\u2019s interface is done. Run the app in the simulator to see how it looks.<\/p>\n<p><img decoding=\"async\" class=\"alignnone size-large wp-image-2774\" src=\"https:\/\/intelligentbee.com\/blog\/wp-content\/uploads\/2017\/07\/1-QVPAlQLqZrHnu_LWntES8w-576x1024.png\" alt=\"\" width=\"525\" height=\"933\" srcset=\"https:\/\/intelligentbee.com\/blog\/wp-content\/uploads\/2017\/07\/1-QVPAlQLqZrHnu_LWntES8w-576x1024.png 576w, https:\/\/intelligentbee.com\/blog\/wp-content\/uploads\/2017\/07\/1-QVPAlQLqZrHnu_LWntES8w-169x300.png 169w, https:\/\/intelligentbee.com\/blog\/wp-content\/uploads\/2017\/07\/1-QVPAlQLqZrHnu_LWntES8w.png 750w\" sizes=\"(max-width: 525px) 100vw, 525px\" \/><\/p>\n<p class=\"graf graf--p\">Now it\u2019s time to write some code.<\/p>\n<h2><span class=\"ez-toc-section\" id=\"Taking_a_Photo\"><\/span>Taking a\u00a0Photo<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p class=\"graf graf--p\">With the main.storyboard still open, select the button from the first screen then open the <strong class=\"markup--strong markup--p-strong\">Assistant editor<\/strong> and be sure you have the <code class=\"markup--code markup--p-code\">ViewController.swit<\/code> file open on the right side. Use the manual mode if you have in case the Assistant editor has a problem figuring this out.<\/p>\n<p class=\"graf graf--p\">Now, Ctrl+drag from the button to the code to create a new action (be sure to select <code class=\"markup--code markup--p-code\">Action<\/code> as the Connection\u00a0, set the Name to <code class=\"markup--code markup--p-code\">selectPhotoClicked<\/code> and the Type to <code class=\"markup--code markup--p-code\">UIButton<\/code>):<\/p>\n<p><img decoding=\"async\" class=\"alignnone size-full wp-image-2775\" src=\"https:\/\/intelligentbee.com\/blog\/wp-content\/uploads\/2017\/07\/1-nAKTd080vQX1z2fHidFqgw.png\" alt=\"\" width=\"800\" height=\"500\" srcset=\"https:\/\/intelligentbee.com\/blog\/wp-content\/uploads\/2017\/07\/1-nAKTd080vQX1z2fHidFqgw.png 800w, https:\/\/intelligentbee.com\/blog\/wp-content\/uploads\/2017\/07\/1-nAKTd080vQX1z2fHidFqgw-300x188.png 300w, https:\/\/intelligentbee.com\/blog\/wp-content\/uploads\/2017\/07\/1-nAKTd080vQX1z2fHidFqgw-768x480.png 768w\" sizes=\"(max-width: 800px) 100vw, 800px\" \/><\/p>\n<pre class=\"theme:xcode lang:swift decode:true \">@IBAction func selectPhotoClicked(_ sender: UIButton) {\r\n\r\n}<\/pre>\n<p class=\"graf graf--p\">Also Ctrl+drag from the two text fields and the button to the code and create three outlets:<\/p>\n<pre class=\"theme:xcode lang:swift decode:true \">@IBOutlet weak var name: UITextField!\r\n@IBOutlet weak var message: UITextField!\r\n@IBOutlet weak var selectPhotoButton: UIButton!<\/pre>\n<p class=\"graf graf--p\">Now let\u2019s start with the most interesting part, choosing a photo. The user will be given a choice to take a photo using the camera or to choose one from the photo library. For this we will use an action sheet.<\/p>\n<p class=\"graf graf--p\">Edit the <code class=\"markup--code markup--p-code\">selectPhotoClicked<\/code> method to add the code for this:<\/p>\n<pre class=\"theme:xcode lang:swift decode:true \">@IBAction func selectPhotoClicked(_ sender: UIButton) {\r\n    let picker = UIImagePickerController()\r\n    picker.delegate = self\r\n    let alert = UIAlertController(title: nil, message: nil, preferredStyle: .actionSheet)\r\n    alert.addAction(UIAlertAction(title: \"Camera\", style: .default, handler: {action in\r\n        picker.sourceType = .camera\r\n        self.present(picker, animated: true, completion: nil)\r\n    }))\r\n    alert.addAction(UIAlertAction(title: \"Photo Library\", style: .default, handler: { action in\r\n        picker.sourceType = .photoLibrary\r\n        self.present(picker, animated: true, completion: nil)\r\n    }))\r\n    alert.addAction(UIAlertAction(title: \"Cancel\", style: .cancel, handler: nil))\r\n    self.present(alert, animated: true, completion: nil)\r\n}<\/pre>\n<p class=\"graf graf--p\">To make this code work we need to make our <code class=\"markup--code markup--p-code\">ViewController<\/code> a delegate for both <code class=\"markup--code markup--p-code\">UIImagePickerControllerDelegate<\/code> and <code class=\"markup--code markup--p-code\">UINavigationControllerDelegate<\/code>. To do this change the line defining the <code class=\"markup--code markup--p-code\">ViewController<\/code> class to the following:<\/p>\n<pre class=\"theme:xcode lang:swift decode:true \">class ViewController: UIViewController, UIImagePickerControllerDelegate, UINavigationControllerDelegate {<\/pre>\n<p class=\"graf graf--p\">If you test now the app will crash with an error like \u201c<em class=\"markup--em markup--p-em\">This app has crashed because it attempted to access privacy-sensitive data without a usage description\u2026<\/em>\u201d. That\u2019s because the app has to ask the user\u2019s permission to access the photo library or the camera and we have to provide a reason for this, reason that will be presented to the user. To do this open the <code class=\"markup--code markup--p-code\">Info.plist<\/code> file and add a two new items:<\/p>\n<ul class=\"postList\">\n<li class=\"graf graf--li\"><code class=\"markup--code markup--li-code\">Privacy - Photo Library Usage Description<\/code> with a string value of <code class=\"markup--code markup--li-code\">Access to the photo library is needed in order to be able to choose a photo to be shared by the app<\/code>.<\/li>\n<li class=\"graf graf--li\"><code class=\"markup--code markup--li-code\">Privacy - Camera Usage Description<\/code> with a string value of <code class=\"markup--code markup--li-code\">Access to the camera is needed in order to be able to take a photo to be shared by the app<\/code>.<\/li>\n<\/ul>\n<p class=\"graf graf--p\">Also, if you try to choose the \u201ccamera\u201d option in the simulator, the app will crash again because the simulator has no camera (\u201c<em class=\"markup--em markup--p-em\">Source type 1 not available<\/em>\u201d). We need to add a test for this and only present the option if the camera is available:<\/p>\n<pre class=\"theme:xcode lang:swift decode:true \">if UIImagePickerController.isSourceTypeAvailable(.camera) {\r\n    alert.addAction(UIAlertAction(title: \"Camera\", style: .default, handler: {action in\r\n        picker.sourceType = .camera\r\n        self.present(picker, animated: true, completion: nil)\r\n    }))\r\n}<\/pre>\n<p class=\"graf graf--p\">One more thing to fix before we start handling the actual images: try to run the app on an iPad (in the simulator or on a real device). The app crashes one more time\u00a0\ud83d\ude41<\/p>\n<p class=\"graf graf--p\"><em class=\"markup--em markup--p-em\">Your application has presented a UIAlertController of style UIAlertControllerStyleActionSheet. The modalPresentationStyle of a UIAlertController with this style is UIModalPresentationPopover. You must provide location information for this popover through the alert controller\u2019s popoverPresentationController. You must provide either a sourceView and sourceRect or a barButtonItem. If this information is not known when you present the alert controller, you may provide it in the UIPopoverPresentationControllerDelegate method -prepareForPopoverPresentation.<\/em><\/p>\n<p class=\"graf graf--p\">That\u2019s because the <code class=\"markup--code markup--p-code\">UIAlertController<\/code> on an iPad is presented like a popover (<code class=\"markup--code markup--p-code\">UIModalPresentationPopover<\/code>) and it needs a position to be shown at. To do this we will have to test if we have a <code class=\"markup--code markup--p-code\">popoverPresentationController<\/code> in the <code class=\"markup--code markup--p-code\">alert<\/code> and, if true, set it\u2019s <code class=\"markup--code markup--p-code\">sourceView<\/code> and <code class=\"markup--code markup--p-code\">sourceRect<\/code> (we are using an Swift <code class=\"markup--code markup--p-code\">optional<\/code> for this, as the code after the question mark will be executed only if the <code class=\"markup--code markup--p-code\">popoverPresentationController<\/code> is not <code class=\"markup--code markup--p-code\">nil<\/code>):<\/p>\n<pre class=\"theme:xcode lang:swift decode:true \">alert.addAction(UIAlertAction(title: \"Cancel\", style: .cancel, handler: nil))\r\n\/\/ on iPad this is a popover\r\nalert.popoverPresentationController?.sourceView = self.view\r\nalert.popoverPresentationController?.sourceRect = selectPhotoButton.frame\r\nself.present(alert, animated: true, completion: nil)<\/pre>\n<p class=\"graf graf--p\">We also need to make the photo selection from the library to be shown as a popover on an iPad:<\/p>\n<pre class=\"theme:xcode lang:swift decode:true \">alert.addAction(UIAlertAction(title: \"Photo Library\", style: .default, handler: { action in\r\n    picker.sourceType = .photoLibrary\r\n    \/\/ on iPad we are required to present this as a popover\r\n    if UIDevice.current.userInterfaceIdiom == .pad {\r\n        picker.modalPresentationStyle = .popover\r\n        picker.popoverPresentationController?.sourceView = self.view\r\n        picker.popoverPresentationController?.sourceRect = self.selectPhotoButton.frame\r\n    }\r\n    self.present(picker, animated: true, completion: nil)\r\n}))<\/pre>\n<p class=\"graf graf--p\">Now everything should be fine. Let\u2019s see how to handle the image the user chooses.<\/p>\n<p class=\"graf graf--p\">We already added a View Controller in the Main.storyboard to show the final image to the user but we need an associated view controller class for it so we have a place to write the code involved in the process.<\/p>\n<p class=\"graf graf--p\">From the <strong class=\"markup--strong markup--p-strong\">File<\/strong> menu select <strong class=\"markup--strong markup--p-strong\">New -&gt; File\u2026<\/strong> then choose the <strong class=\"markup--strong markup--p-strong\">Cocoa Touch Class<\/strong> option and click <strong class=\"markup--strong markup--p-strong\">Next<\/strong>. Name the new class <code class=\"markup--code markup--p-code\">ShareViewController<\/code> and be sure to set it as a subclass of <code class=\"markup--code markup--p-code\">UIViewController<\/code>, no <code class=\"markup--code markup--p-code\">XIB<\/code>, <code class=\"markup--code markup--p-code\">Swift<\/code> language.<\/p>\n<p><img decoding=\"async\" class=\"alignnone size-full wp-image-2777\" src=\"https:\/\/intelligentbee.com\/blog\/wp-content\/uploads\/2017\/07\/1-75SbWYZ0VeagbRlR-f1N9Q.png\" alt=\"\" width=\"800\" height=\"500\" srcset=\"https:\/\/intelligentbee.com\/blog\/wp-content\/uploads\/2017\/07\/1-75SbWYZ0VeagbRlR-f1N9Q.png 800w, https:\/\/intelligentbee.com\/blog\/wp-content\/uploads\/2017\/07\/1-75SbWYZ0VeagbRlR-f1N9Q-300x188.png 300w, https:\/\/intelligentbee.com\/blog\/wp-content\/uploads\/2017\/07\/1-75SbWYZ0VeagbRlR-f1N9Q-768x480.png 768w\" sizes=\"(max-width: 800px) 100vw, 800px\" \/><\/p>\n<p class=\"graf graf--p\">Click <strong class=\"markup--strong markup--p-strong\">Next<\/strong> one more time and be sure to have the <code class=\"markup--code markup--p-code\">PicTravel<\/code> <strong class=\"markup--strong markup--p-strong\">Group<\/strong> selected and <code class=\"markup--code markup--p-code\">PicTravel<\/code> <strong class=\"markup--strong markup--p-strong\">target<\/strong> checked. Then <strong class=\"markup--strong markup--p-strong\">Create<\/strong> the file.<\/p>\n<p class=\"graf graf--p\">Go back to the <code class=\"markup--code markup--p-code\">Main.storyboard<\/code> and select the second view controller and set it\u2019s class to the new <code class=\"markup--code markup--p-code\">ShareViewController<\/code> we just created (you can do this from the Identity inspector, the <strong class=\"markup--strong markup--p-strong\">Class<\/strong> dropdown).<\/p>\n<p><img decoding=\"async\" class=\"alignnone size-full wp-image-2779\" src=\"https:\/\/intelligentbee.com\/blog\/wp-content\/uploads\/2017\/07\/1-rYCc5ogQJ4IIflprjDb8rQ.png\" alt=\"\" width=\"800\" height=\"500\" srcset=\"https:\/\/intelligentbee.com\/blog\/wp-content\/uploads\/2017\/07\/1-rYCc5ogQJ4IIflprjDb8rQ.png 800w, https:\/\/intelligentbee.com\/blog\/wp-content\/uploads\/2017\/07\/1-rYCc5ogQJ4IIflprjDb8rQ-300x188.png 300w, https:\/\/intelligentbee.com\/blog\/wp-content\/uploads\/2017\/07\/1-rYCc5ogQJ4IIflprjDb8rQ-768x480.png 768w\" sizes=\"(max-width: 800px) 100vw, 800px\" \/><\/p>\n<p class=\"graf graf--p\">Now, with the view controller still selected, open the assistant editor and make sure it is set to automatically open the associated file. This should be the <code class=\"markup--code markup--p-code\">ShareViewController<\/code> class. Ctrl+drag from the Image View, Activity Indicator and the Label to the class to create outlets for them:<\/p>\n<pre class=\"theme:xcode lang:swift decode:true \">@IBOutlet weak var imageView: UIImageView!\r\n@IBOutlet weak var activityIndicator: UIActivityIndicatorView!\r\n@IBOutlet weak var titleLabel: UILabel!<\/pre>\n<p><img decoding=\"async\" class=\"alignnone size-full wp-image-2780\" src=\"https:\/\/intelligentbee.com\/blog\/wp-content\/uploads\/2017\/07\/1-CW-2PDM76PGGiQBpvBe7Hw.png\" alt=\"\" width=\"800\" height=\"500\" srcset=\"https:\/\/intelligentbee.com\/blog\/wp-content\/uploads\/2017\/07\/1-CW-2PDM76PGGiQBpvBe7Hw.png 800w, https:\/\/intelligentbee.com\/blog\/wp-content\/uploads\/2017\/07\/1-CW-2PDM76PGGiQBpvBe7Hw-300x188.png 300w, https:\/\/intelligentbee.com\/blog\/wp-content\/uploads\/2017\/07\/1-CW-2PDM76PGGiQBpvBe7Hw-768x480.png 768w\" sizes=\"(max-width: 800px) 100vw, 800px\" \/><\/p>\n<p class=\"graf graf--p\">Also add some new variables for the user\u2019s image, name and message:<\/p>\n<pre class=\"theme:xcode lang:swift decode:true \">var image: UIImage!\r\nvar name: String!\r\nvar message: String!<\/pre>\n<p class=\"graf graf--p\">So, here\u2019s what we will do next: when the user chooses an image, we instantiate the ShareViewController, set its <code class=\"markup--code markup--p-code\">image<\/code>, <code class=\"markup--code markup--p-code\">name<\/code> and <code class=\"markup--code markup--p-code\">message<\/code> properties to the user\u2019s data then present the <code class=\"markup--code markup--p-code\">ShareViewController<\/code>.<\/p>\n<p class=\"graf graf--p\">To do this we need to create a <code class=\"markup--code markup--p-code\">segue<\/code> (transition). Close the assistant editor then, in the <code class=\"markup--code markup--p-code\">Main.storyboard<\/code>, Ctrl+drag from the first \u201cView Controller\u201d (click on the yellow symbol from the top-right) to the \u201cShare View Controller\u201d and define a \u201cPresent Modally\u201d segue. then click on the created segue and set it\u2019s identifier to <code class=\"markup--code markup--p-code\">showImageSegue<\/code> (we will need this later in the code to identify this specific segue).<\/p>\n<p><img decoding=\"async\" class=\"alignnone size-full wp-image-2781\" src=\"https:\/\/intelligentbee.com\/blog\/wp-content\/uploads\/2017\/07\/1-dcJS6EZfdNrquRiePw5gaA.png\" alt=\"\" width=\"800\" height=\"500\" srcset=\"https:\/\/intelligentbee.com\/blog\/wp-content\/uploads\/2017\/07\/1-dcJS6EZfdNrquRiePw5gaA.png 800w, https:\/\/intelligentbee.com\/blog\/wp-content\/uploads\/2017\/07\/1-dcJS6EZfdNrquRiePw5gaA-300x188.png 300w, https:\/\/intelligentbee.com\/blog\/wp-content\/uploads\/2017\/07\/1-dcJS6EZfdNrquRiePw5gaA-768x480.png 768w\" sizes=\"(max-width: 800px) 100vw, 800px\" \/><\/p>\n<p class=\"graf graf--p\">Now open our <code class=\"markup--code markup--p-code\">ViewController<\/code> class. Add a new method to be called when the user selects an image (this is part of the <code class=\"markup--code markup--p-code\">UIImagePickerControllerDelegate<\/code>):<\/p>\n<pre class=\"theme:xcode lang:swift decode:true \">func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {\r\n    dismiss(animated: true, completion: nil)\r\n    image = info[UIImagePickerControllerOriginalImage] as! UIImage\r\n    performSegue(withIdentifier: \"showImageSegue\", sender: self)\r\n}<\/pre>\n<p class=\"graf graf--p\">Here\u2019s what this method does:<\/p>\n<ul class=\"postList\">\n<li class=\"graf graf--li\">dismiss the image picker controller<\/li>\n<li class=\"graf graf--li\">get the image in a class variable<\/li>\n<li class=\"graf graf--li\">present the ShareViewController by performing the <code class=\"markup--code markup--li-code\">showImageSegue<\/code> segue<\/li>\n<\/ul>\n<p class=\"graf graf--p\">For this we need a new image variable to be defined in our <code class=\"markup--code markup--p-code\">ViewController<\/code> class:<\/p>\n<pre class=\"theme:xcode lang:swift decode:true \">var image: UIImage!<\/pre>\n<p class=\"graf graf--p\">To send the data to the ShareViewController, we will use a method that is called just before the segue to the new view controller happens:<\/p>\n<pre class=\"theme:xcode lang:swift decode:true \">override func prepare(for segue: UIStoryboardSegue, sender: Any?) {\r\n    if segue.identifier == \"showImageSegue\" {\r\n        if let shareViewController = segue.destination as? ShareViewController {\r\n            shareViewController.image = self.image\r\n            shareViewController.name = name.text ?? \"\"\r\n            shareViewController.message = message.text ?? \"\"\r\n        }\r\n    }\r\n}<\/pre>\n<p class=\"graf graf--p\">Now run the app. After the user selects an image, the second view controller should be presented to the user. But\u2026 we have no way to close it. Let\u2019s do this next.<\/p>\n<p class=\"graf graf--p\">Still in the <code class=\"markup--code markup--p-code\">ViewController<\/code>, create an action that will be called when the <code class=\"markup--code markup--p-code\">ShareViewController<\/code> will exit (here we will also set the image to <code class=\"markup--code markup--p-code\">nil<\/code> to free the memory because we don\u2019t need it anymore):<\/p>\n<pre class=\"theme:xcode lang:swift decode:true \">@IBAction func exit(unwindSegue: UIStoryboardSegue) {\r\n    image = nil\r\n}<\/pre>\n<p class=\"graf graf--p\">Back to the <code class=\"markup--code markup--p-code\">Main.storyboard<\/code>, Ctrl+drag from the <strong class=\"markup--strong markup--p-strong\">Close<\/strong> button to the exit symbol from the top-right of the ShareViewController and select the exit method when prompted.<\/p>\n<p><img decoding=\"async\" class=\"alignnone size-full wp-image-2782\" src=\"https:\/\/intelligentbee.com\/blog\/wp-content\/uploads\/2017\/07\/1-fuzVhVUDakFk-tVaIEj34A.png\" alt=\"\" width=\"800\" height=\"500\" srcset=\"https:\/\/intelligentbee.com\/blog\/wp-content\/uploads\/2017\/07\/1-fuzVhVUDakFk-tVaIEj34A.png 800w, https:\/\/intelligentbee.com\/blog\/wp-content\/uploads\/2017\/07\/1-fuzVhVUDakFk-tVaIEj34A-300x188.png 300w, https:\/\/intelligentbee.com\/blog\/wp-content\/uploads\/2017\/07\/1-fuzVhVUDakFk-tVaIEj34A-768x480.png 768w\" sizes=\"(max-width: 800px) 100vw, 800px\" \/><\/p>\n<p class=\"graf graf--p\">This should solve our problem of closing the second screen.<\/p>\n<p class=\"graf graf--p\">Let\u2019s get now to the main objective of our app: get the user\u2019s location, generate a map image and put the photo the user selected on top of it together with the name, location and message.<\/p>\n<p class=\"graf graf--p\">To continue, add some constants to the ShareViewController class that will be used in the code that follows:<\/p>\n<pre class=\"theme:xcode lang:swift decode:true \">\/\/ some constants used to generate the final image\r\nlet finalImageMaxDimension: CGFloat = 2048\r\nlet finalImageBorderWidth: CGFloat = 4\r\nlet userImageMaxDimension: CGFloat = 1200\r\nlet userImageBorderWidth: CGFloat = 20\r\nlet userImageX: CGFloat = 100\r\nlet userImageY: CGFloat = 160\r\nlet mapRegionDistance: CLLocationDistance = 600\r\nlet rotateContentByDegrees: CGFloat = -4\r\nlet userMessageMaxLength = 100\r\nlet textMargin: CGFloat = 280\r\nlet userMessageTopMargin: CGFloat = 60\r\nlet userNameTopMargin: CGFloat = 80\r\nlet userNameHeight: CGFloat = 120<\/pre>\n<h2><span class=\"ez-toc-section\" id=\"Getting_Current_User_Location\"><\/span>Getting Current User\u00a0Location<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p class=\"graf graf--p\">First we need to add a new key to <code class=\"markup--code markup--p-code\">Info.plist<\/code>, <code class=\"markup--code markup--p-code\">Privacy - Location When In Use Usage Description<\/code> with the value of <code class=\"markup--code markup--p-code\">Current location is needed to generate a map image of your location<\/code>.<\/p>\n<p class=\"graf graf--p\">Now we need to import <code class=\"markup--code markup--p-code\">CoreLocation<\/code> into our ShareViewController:<\/p>\n<pre class=\"theme:xcode lang:swift decode:true \">import UIKit\r\nimport CoreLocation<\/pre>\n<p class=\"graf graf--p\">Declare a new <code class=\"markup--code markup--p-code\">locationManager<\/code> variable:<\/p>\n<pre class=\"theme:xcode lang:swift decode:true \">var locationManager:CLLocationManager!<\/pre>\n<p class=\"graf graf--p\">Add a new method that will start the process of finding the user location:<\/p>\n<pre class=\"theme:xcode lang:swift decode:true \">func getCurrentLocation() {\r\n    locationManager = CLLocationManager()\r\n    locationManager.delegate = self\r\n    locationManager.desiredAccuracy = kCLLocationAccuracyNearestTenMeters\r\n    locationManager.requestWhenInUseAuthorization()\r\n    if (CLLocationManager.authorizationStatus() == .denied) {\r\n        showError(title: \"Location Access Denied\", message: \"The location permission was not authorized. Please enable it in Privacy Settings to allow the app to get your location and generate a map image based on that.\")\r\n    }\r\n        \r\n    if CLLocationManager.locationServicesEnabled() {\r\n        locationManager.startUpdatingLocation()\r\n    }\r\n}<\/pre>\n<p class=\"graf graf--p\">For this to work we need to implement the <code class=\"markup--code markup--p-code\">CLLocationManagerDelegate<\/code> protocol:<\/p>\n<pre class=\"theme:xcode lang:swift decode:true \">class ShareViewController: UIViewController, CLLocationManagerDelegate {<\/pre>\n<p class=\"graf graf--p\">We also need to define the <code class=\"markup--code markup--p-code\">showError<\/code> function:<\/p>\n<pre class=\"theme:xcode lang:swift decode:true \">func showError(title: String, message: String)\r\n{\r\n    let alert = UIAlertController(title: title, message: message, preferredStyle: .alert)\r\n    let action = UIAlertAction(title: \"OK\", style: .default, handler: { _ in\r\n        self.dismiss(animated: true, completion: nil)\r\n    })\r\n    alert.addAction(action)\r\n        \r\n    present(alert, animated: true, completion: nil)\r\n}<\/pre>\n<p class=\"graf graf--p\">Now implement the method of the <code class=\"markup--code markup--p-code\">CLLocationManagerDelegate<\/code> protocol that is called when we get a location update:<\/p>\n<pre class=\"theme:xcode lang:swift decode:true \">func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {\r\n    let location = locations[0]\r\n    manager.stopUpdatingLocation()\r\n        \r\n    \/\/ get city &amp; country name\r\n    let geocoder = CLGeocoder()\r\n    geocoder.reverseGeocodeLocation(location, completionHandler: { placemarks, error in\r\n        if error != nil {\r\n            self.showError(title: \"Whoops...\", message: error!.localizedDescription)\r\n        } else {\r\n            let placemark = placemarks?[0]\r\n            self.locationString = (placemark?.administrativeArea ?? \"\") + \", \" + (placemark?.country ?? \"\")\r\n            self.generateMapImage(location: location)\r\n        }\r\n    })\r\n}<\/pre>\n<p class=\"graf graf--p\">This method will receive the user\u2019s location, stop the location updates (because we don\u2019t need them anymore) and calls a <code class=\"markup--code markup--p-code\">generateMapImage<\/code> function (that we\u2019ll define later) with the retrieved location as an argument. It also uses the Apple\u2019s geocoder service to find out the city and country name for the retrieved location and puts them in a new class variable <code class=\"markup--code markup--p-code\">locationString:<\/code><\/p>\n<pre class=\"theme:xcode lang:swift decode:true \">var locationString = \"\"<\/pre>\n<h2><span class=\"ez-toc-section\" id=\"Generate_the_Map_Image\"><\/span>Generate the Map\u00a0Image<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p class=\"graf graf--p\">To generate the map image we will use the following function:<\/p>\n<pre class=\"theme:xcode lang:swift decode:true \">func generateMapImage(location userLocation: CLLocation) {\r\n    let mapSnapshotOptions = MKMapSnapshotOptions()\r\n        \r\n    \/\/ Set the region of the map that is rendered.\r\n    let location = CLLocationCoordinate2DMake(userLocation.coordinate.latitude, userLocation.coordinate.longitude)\r\n    let region = MKCoordinateRegionMakeWithDistance(location, mapRegionDistance, mapRegionDistance)\r\n    mapSnapshotOptions.region = region\r\n        \r\n    \/\/ Set the size of the image output.\r\n    mapSnapshotOptions.size = calculateMapImageSize(image: self.image)\r\n        \r\n    let snapShotter = MKMapSnapshotter(options: mapSnapshotOptions)\r\n    snapShotter.start(completionHandler: { snapShot, error in\r\n        if error != nil {\r\n            self.showError(title: \"Whoops1...\", message: error!.localizedDescription)\r\n        } else {\r\n            self.mapImage = snapShot?.image\r\n            self.activityIndicator.stopAnimating()\r\n            self.generateFinalImage()\r\n        }\r\n    })\r\n}<\/pre>\n<p class=\"graf graf--p\">You need to import <code class=\"markup--code markup--p-code\">MapKit<\/code> into <code class=\"markup--code markup--p-code\">ShareViewController<\/code>:<\/p>\n<pre class=\"theme:xcode lang:swift decode:true \">import MapKit<\/pre>\n<p class=\"graf graf--p\">Also a new class variable is used:<\/p>\n<pre class=\"theme:xcode lang:swift decode:true \">var mapImage: UIImage!<\/pre>\n<p class=\"graf graf--p\">To calculate the map size we used another function, <code class=\"markup--code markup--p-code\">calculateMapImageSize<\/code> that returns a <code class=\"markup--code markup--p-code\">CGSize<\/code> object to be used when generating the map image:<\/p>\n<pre class=\"theme:xcode lang:swift decode:true \">func calculateMapImageSize() -&gt; CGSize  {\r\n    let maxSize = finalImageMaxDimension - 2 * finalImageBorderWidth\r\n    if image.size.width &gt; image.size.height {\r\n        return CGSize(width: maxSize, height: round(maxSize * image.size.height \/ image.size.width))\r\n    } else {\r\n        return CGSize(width: round(maxSize * image.size.width \/ image.size.height), height: maxSize)\r\n    }\r\n}<\/pre>\n<h2><span class=\"ez-toc-section\" id=\"Building_the_Final_Image\"><\/span>Building the Final\u00a0Image<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p class=\"graf graf--p\">The last thing we need to do is to generate the final image with all the pieces put together:<\/p>\n<pre class=\"theme:xcode lang:swift decode:true \">func generateFinalImage() {\r\n    let size = CGSize(width: mapImage.size.width + 2 * finalImageBorderWidth, height: mapImage.size.height + 2 * finalImageBorderWidth)\r\n    let userImageSize = calculateUserImageFinalSize()\r\n        \r\n    \/\/ start drawing context\r\n    UIGraphicsBeginImageContextWithOptions(size, true, 0.0)\r\n    let context = UIGraphicsGetCurrentContext()\r\n        \r\n    \/\/ draw the white background\r\n    let bgRectangle = CGRect(x: 0, y: 0, width: mapImage.size.width + 2 * finalImageBorderWidth, height: mapImage.size.height + 2 * finalImageBorderWidth)\r\n    context!.saveGState()\r\n    context!.setFillColor(UIColor.white.cgColor)\r\n    context!.addRect(bgRectangle)\r\n    context!.drawPath(using: .fill)\r\n    context!.restoreGState()\r\n        \r\n    \/\/ draw the map\r\n    mapImage.draw(in: CGRect(x: finalImageBorderWidth, y: finalImageBorderWidth, width: mapImage.size.width, height: mapImage.size.height))\r\n        \r\n    \/\/ draw a semitransparent white rectage over the  map to dim it\r\n    let transparentRectangle = CGRect(x: finalImageBorderWidth, y: finalImageBorderWidth, width: mapImage.size.width, height: mapImage.size.height)\r\n    context!.saveGState()\r\n    context!.setFillColor(UIColor(colorLiteralRed: 255, green: 255, blue: 255, alpha: 0.3).cgColor)\r\n    context!.addRect(transparentRectangle)\r\n    context!.drawPath(using: .fill)\r\n    context!.restoreGState()\r\n        \r\n    \/\/ rotate the context\r\n    context!.rotate(by: (rotateContentByDegrees * CGFloat.pi \/ 180))\r\n        \r\n    \/\/ draw white rectangle\r\n    let rectangle = CGRect(x: userImageX, y: userImageY, width: userImageSize.width + 2 * userImageBorderWidth, height: userImageSize.height + 2 * userImageBorderWidth)\r\n    context!.saveGState()\r\n    context!.setFillColor(UIColor.white.cgColor)\r\n    context!.setShadow(offset: CGSize(width: userImageBorderWidth, height: userImageBorderWidth), blur: 8.0)\r\n    context!.addRect(rectangle)\r\n    context!.drawPath(using: .fill)\r\n    context!.restoreGState()\r\n        \r\n    \/\/ draw user image\r\n    image.draw(in: CGRect(x: userImageX + userImageBorderWidth, y: userImageY + userImageBorderWidth, width: userImageSize.width, height: userImageSize.height))\r\n        \r\n    \/\/ draw message\r\n    var truncatedMessage = message\r\n    if (message.distance(from: message.startIndex, to: message.endIndex) &gt; userMessageMaxLength) {\r\n        truncatedMessage = message.substring(to: message.index(message.startIndex, offsetBy: userMessageMaxLength))\r\n    }\r\n    let messageFont = UIFont(name: \"Noteworthy-Bold\", size: 80)!\r\n    let messageFontAttributes = [\r\n        NSFontAttributeName: messageFont,\r\n        NSForegroundColorAttributeName: UIColor.black,\r\n        ] as [String : Any]\r\n    let messageSize = sizeOfString(string: truncatedMessage!, constrainedToWidth: Double(size.width - textMargin), attributes: messageFontAttributes)\r\n    truncatedMessage!.draw(in: CGRect(x: userImageX + userImageBorderWidth, y: userImageY + userImageBorderWidth + userImageSize.height + userMessageTopMargin, width: size.width - textMargin, height: messageSize.height), withAttributes: messageFontAttributes)\r\n        \r\n    \/\/ draw name, location &amp; date\r\n    let nameFont = UIFont(name: \"Noteworthy\", size: 58)!\r\n    let nameFontAttributes = [\r\n        NSFontAttributeName: nameFont,\r\n        NSForegroundColorAttributeName: UIColor.black,\r\n        ] as [String : Any]\r\n    let dateFormatter = DateFormatter()\r\n    dateFormatter.dateStyle = .long\r\n    dateFormatter.timeStyle = .none\r\n        \r\n    var nameString = \"\"\r\n    if(name != \"\") {\r\n        nameString = name + \" - \" + dateFormatter.string(from: Date()) + \", \" + locationString\r\n    } else {\r\n        nameString = dateFormatter.string(from: Date()) + \", \" + locationString\r\n    }\r\n    nameString.draw(in: CGRect(x: userImageX + userImageBorderWidth, y: userImageY + userImageBorderWidth + userImageSize.height + messageSize.height + userNameTopMargin, width: size.width - textMargin, height: userNameHeight), withAttributes: nameFontAttributes)\r\n        \r\n    \/\/ get final image\r\n    let finalImage = UIGraphicsGetImageFromCurrentImageContext()\r\n        \r\n    \/\/ end drawing context\r\n    UIGraphicsEndImageContext()\r\n        \r\n    \/\/ show the final image to the user &amp; update tha status label\r\n    imageView.image = finalImage\r\n    titleLabel.text = \"You can now share your image.\"\r\n}<\/pre>\n<p class=\"graf graf--p\">Here we used two helper methods, <code class=\"markup--code markup--p-code\">calculateUserImageFinalSize<\/code> and <code class=\"markup--code markup--p-code\">sizeOfString<\/code>. The last one deserves a little attention because it will return a <code class=\"markup--code markup--p-code\">CGSize<\/code> object with the dimensions needed to draw a text with specific attributes.<\/p>\n<pre class=\"theme:xcode lang:swift decode:true \">func calculateUserImageFinalSize() -&gt; CGSize  {\r\n    if image.size.width &gt; image.size.height {\r\n        return CGSize(width: userImageMaxDimension, height: round(userImageMaxDimension * image.size.height \/ image.size.width))\r\n    } else {\r\n        return CGSize(width: round(userImageMaxDimension * image.size.width \/ image.size.height), height: userImageMaxDimension)\r\n    }\r\n}\r\n    \r\nfunc sizeOfString (string: String, constrainedToWidth width: Double, attributes: [String: Any]) -&gt; CGSize {\r\n    let attString = NSAttributedString(string: string,attributes: attributes)\r\n    let framesetter = CTFramesetterCreateWithAttributedString(attString)\r\n        \r\n    return CTFramesetterSuggestFrameSizeWithConstraints(framesetter, CFRange(location: 0,length: 0), nil, CGSize(width: width, height: .greatestFiniteMagnitude), nil)\r\n}<\/pre>\n<p class=\"graf graf--p\">Now that we have everything in place, we need to start the whole process when the ShareViewController is loaded and presented to the user:<\/p>\n<pre class=\"theme:xcode lang:swift decode:true \">override func viewDidAppear(_ animated: Bool) {\r\n    super.viewDidAppear(animated)\r\n    getCurrentLocation()\r\n}<\/pre>\n<p class=\"graf graf--p\">Test the app. Enter your name, a short message and select a photo. You should get the following result:<\/p>\n<p><img decoding=\"async\" class=\"alignnone size-large wp-image-2784\" src=\"https:\/\/intelligentbee.com\/blog\/wp-content\/uploads\/2017\/07\/1-Uh1_9fyYxZWaKPv-ZD_h1g-576x1024.png\" alt=\"\" width=\"525\" height=\"933\" srcset=\"https:\/\/intelligentbee.com\/blog\/wp-content\/uploads\/2017\/07\/1-Uh1_9fyYxZWaKPv-ZD_h1g-576x1024.png 576w, https:\/\/intelligentbee.com\/blog\/wp-content\/uploads\/2017\/07\/1-Uh1_9fyYxZWaKPv-ZD_h1g-169x300.png 169w, https:\/\/intelligentbee.com\/blog\/wp-content\/uploads\/2017\/07\/1-Uh1_9fyYxZWaKPv-ZD_h1g.png 750w\" sizes=\"(max-width: 525px) 100vw, 525px\" \/><\/p>\n<h2><span class=\"ez-toc-section\" id=\"Sharing_the_Final_Image\"><\/span>Sharing the Final\u00a0Image<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p class=\"graf graf--p\">Ok, now let\u2019s see how do we share the resulted image. To do this we will use an <a class=\"markup--anchor markup--p-anchor\" href=\"https:\/\/developer.apple.com\/documentation\/uikit\/uiactivityviewcontroller\" target=\"_blank\" rel=\"noopener\" data-href=\"https:\/\/developer.apple.com\/documentation\/uikit\/uiactivityviewcontroller\">UIActivityViewController<\/a>.<\/p>\n<p class=\"graf graf--p\">Add a new shareImage action for the <strong class=\"markup--strong markup--p-strong\">Share Image!<\/strong> button using Ctrl+drag into the <code class=\"markup--code markup--p-code\">ShareViewController<\/code> like we did earlier for the photo button:<\/p>\n<pre class=\"theme:xcode lang:swift decode:true \">@IBAction func shareImage(_ sender: UIButton) {\r\n}<\/pre>\n<p class=\"graf graf--p\">The code for the actual sharing is pretty simple:<\/p>\n<pre class=\"theme:xcode lang:swift decode:true \">@IBAction func shareImage(_ sender: UIButton) {\r\n    let activityViewController = UIActivityViewController(activityItems: [image], applicationActivities: nil)\r\n    activityViewController.popoverPresentationController?.sourceView = self.view\r\n    present(activityViewController, animated: true, completion: nil)\r\n}<\/pre>\n<p class=\"graf graf--p\">Try it! Now you can save the image or share it with your friends &amp; family using the installed apps on your device.<\/p>\n<h2><span class=\"ez-toc-section\" id=\"Final_Touches\"><\/span>Final Touches<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p class=\"graf graf--p\">To finish the app we need to do two more things:<\/p>\n<ul class=\"postList\">\n<li class=\"graf graf--li\">add an app icon<\/li>\n<li class=\"graf graf--li\">make the startup screen look good<\/li>\n<\/ul>\n<p class=\"graf graf--p\">To add an app icon, first download the images from <a class=\"markup--anchor markup--p-anchor\" href=\"https:\/\/github.com\/intelligentbee\/PicTravel\/tree\/master\/PicTravel\/Assets.xcassets\/AppIcon.appiconset\" target=\"_blank\" rel=\"noopener\" data-href=\"https:\/\/github.com\/intelligentbee\/PicTravel\/tree\/master\/PicTravel\/Assets.xcassets\/AppIcon.appiconset\">here<\/a>, then open the <code class=\"markup--code markup--p-code\">Assets.xcassets<\/code> from the left panel, select the AppIcon item and drag&amp;drop downloaded images to their respective placeholders.<\/p>\n<p><img decoding=\"async\" class=\"alignnone size-full wp-image-2785\" src=\"https:\/\/intelligentbee.com\/blog\/wp-content\/uploads\/2017\/07\/1-0nn925l4LY-sKBPrFzIu0Q.png\" alt=\"\" width=\"800\" height=\"500\" srcset=\"https:\/\/intelligentbee.com\/blog\/wp-content\/uploads\/2017\/07\/1-0nn925l4LY-sKBPrFzIu0Q.png 800w, https:\/\/intelligentbee.com\/blog\/wp-content\/uploads\/2017\/07\/1-0nn925l4LY-sKBPrFzIu0Q-300x188.png 300w, https:\/\/intelligentbee.com\/blog\/wp-content\/uploads\/2017\/07\/1-0nn925l4LY-sKBPrFzIu0Q-768x480.png 768w\" sizes=\"(max-width: 800px) 100vw, 800px\" \/><\/p>\n<p class=\"graf graf--p\">To change the startup screen\u00a0, which is white right now, open the <code class=\"markup--code markup--p-code\">LaunchScreen.storyboard<\/code> from the left panel and drag an Image View to it. Add constraints so it covers the entire screen, select the <code class=\"markup--code markup--p-code\">Background<\/code> <strong class=\"markup--strong markup--p-strong\">Image<\/strong> and set the <strong class=\"markup--strong markup--p-strong\">Content Mode<\/strong> to <code class=\"markup--code markup--p-code\">Aspect Fill<\/code> (it will look exactly like our main app&#8217;s screen background).<\/p>\n<p class=\"graf graf--p\">That\u2019s it! You can now run the app and even install it on your device to take it out in the wild.<\/p>\n<p class=\"graf graf--p\">The code for this app is available on github: <a class=\"markup--anchor markup--p-anchor\" href=\"https:\/\/github.com\/intelligentbee\/PicTravel\" target=\"_blank\" rel=\"nofollow noopener\" data-href=\"https:\/\/github.com\/intelligentbee\/PicTravel\">https:\/\/github.com\/intelligentbee\/PicTravel<\/a><\/p>\n<p class=\"graf graf--p\">You can also download the final app from the App Store: <a class=\"markup--anchor markup--p-anchor\" href=\"https:\/\/itunes.apple.com\/us\/app\/pictravel\/id1263495901?mt=8\" target=\"_blank\" rel=\"noopener\" data-href=\"https:\/\/itunes.apple.com\/us\/app\/pictravel\/id1263495901?mt=8\">https:\/\/itunes.apple.com\/us\/app\/pictravel\/id1263495901?mt=8<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Hello! I want to show you how to build a relative simple photo sharing app with a twist: your images [&hellip;]<\/p>\n","protected":false},"author":3,"featured_media":2750,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[75,79,80],"tags":[],"yst_prominent_words":[1168,1178,1177,1176,1174,1173,1172,1171,1170,1169,273,1167,1166,1165,1164,1122,1121,1117,483],"post_mailing_queue_ids":[],"_links":{"self":[{"href":"https:\/\/intelligentbee.com\/blog\/wp-json\/wp\/v2\/posts\/2748"}],"collection":[{"href":"https:\/\/intelligentbee.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/intelligentbee.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/intelligentbee.com\/blog\/wp-json\/wp\/v2\/users\/3"}],"replies":[{"embeddable":true,"href":"https:\/\/intelligentbee.com\/blog\/wp-json\/wp\/v2\/comments?post=2748"}],"version-history":[{"count":5,"href":"https:\/\/intelligentbee.com\/blog\/wp-json\/wp\/v2\/posts\/2748\/revisions"}],"predecessor-version":[{"id":133353,"href":"https:\/\/intelligentbee.com\/blog\/wp-json\/wp\/v2\/posts\/2748\/revisions\/133353"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/intelligentbee.com\/blog\/wp-json\/wp\/v2\/media\/2750"}],"wp:attachment":[{"href":"https:\/\/intelligentbee.com\/blog\/wp-json\/wp\/v2\/media?parent=2748"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/intelligentbee.com\/blog\/wp-json\/wp\/v2\/categories?post=2748"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/intelligentbee.com\/blog\/wp-json\/wp\/v2\/tags?post=2748"},{"taxonomy":"yst_prominent_words","embeddable":true,"href":"https:\/\/intelligentbee.com\/blog\/wp-json\/wp\/v2\/yst_prominent_words?post=2748"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}