{"componentChunkName":"component---src-templates-legacy-tutorial-page-js","path":"/oa/tutorials/build-a-tip-calculator-in-swift-4/ui-layout/","result":{"pageContext":{"tutorial":{"id":"T0E6OlR1dG9yaWFsLTEy","slug":"build-a-tip-calculator-in-swift-4","title":"Build a Tip Calculator in Swift 4","previewText":"This tutorial will guide you through making a tip calculator! Learn autolayout and get more comfortable with Xcode.\n","heroImagePath":"https://raw.githubusercontent.com/MakeSchool-Tutorials/Tip-Calculator-Swift4/master/cover.png","heroImageFile":{"childImageSharp":{"gatsbyImageData":{"layout":"constrained","placeholder":{"fallback":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAYAAACNiR0NAAAACXBIWXMAAAsTAAALEwEAmpwYAAAEXElEQVQ4y42U+0+TZxTH379j8QLeEBGEFnBBRWHqcJoJBFcVWqC0IlBAbB2oGCw62OblVzNRvM64zB/UTX9ZtiXO7JfFTH8YgQnSQukVewNa2r70s7xPh9sSk/lNvjnnOc/3nDzved7zSCVllZSUVbB1517B0l2Vgts+LGdT6W7WqTZTVLJbrP/RllO8Yy+lZSmtEttcuof16mKkSCRKdH4ej8fLxMQks3NzzM7O4fX5GBoaQqM18OSXXwmFQsxFIkLr801jn5ggPDMjtH5/gOHhYeob25BsNjtjY2O43W7+jUQiIayhuYM/hobFvt1uZ3R0FKfT+R9tLBYX1tzVg5RMJlhYUAIyb4POYOLV+LjwFZ0sxyD5du2RY91IFy7eYZFfnrvFZ/3X6f/8Jj2nB7j7zQ80mo4ycPUeFy7e5fyFr99oz52/TV//dfr6b2DtvcqNG49pautEWrFqH8vSKlmytJz0FVWoC/TkF+rJzDrI/gM9tJm7qNF1896SctJXVrEsvZKlyypYvrwCVX49+QV6cjZo2fWRBX1jB9L2ne1sK2khPfMA6m3N3H/4hPsPfhK2+9SAOGGTqY8txS2Ubm+lpNREZq6OtJwa7n77Iw+++5nvHz2lxzqIVt+KtCFXx5qsg2gKjZg3t1CkquP9wgayMjTU1Z2l1dyF4VAv67N15GxIaXerG+gubmWLqp7CfD25WdVUlh/H0GRGylPVkpahobWoiUvbLWzN1lKQrSU7vYpaXa8oqDdYyS8wILRrNRwsMHK7rJMPcnSo1lejWq2h4uNOGpSC6kK96NtaVS0r83Tk5ddTsLGBjHUHMBz6gjZLF4db+shSkgvqhTZLXUd6rpZcpYfK1+TUUKU5hbHZguSwO3HYnEzZXDjtLhw2F1N2F5PjU/i9AfGzPvvtOT7ntIgpWkXntruYsqVy7WOTBHxB2swnkPgf6OqbGRsZ5V3QfvQEUjQSwRuMMOKO8dITwxOcJxqNoIxkIh6n1mBiZGhETE4gECAUDiPLMgvJpCgyOzvL2KtXxCNROizdSLKcIC4neR2awx+KkJCTItnv94uEukNt/Dk0Ivz5+XnkRIJkMimoIBqN8lrRJmSOmE8iLSwsiI2ZcIhwOPT3HMu43Z43BZUTxuIx8TCIEUwmWczz+XyM22zI87FUwXg89QiEw2FBBUrM4XCkChpbGR1++e49XFwEg0HBFJJ4vakT6g+38/uzFwSng7gdHjxOr7CLvmfKi2vSzUxgJnXL9gkXM7NRgqGQKBiJxhi3OXn+YgjfdJCm9mPojVbSVu5jTeZ+VmVoyFPXkb+xgdVrNSK2NK2CXXssGJrNSFduPsLl9rMgJ1AuyB+YYfDWYy5duceDx0/RGkxcHriH1XoNa+8gp61XOXP2GmfOXsdqHRSxk91fcXngIS1HupCqqo2i8YamDsH6xnb21RipqjbwibYRddEOao0m2izHaen4FFNHp7CL/iKVEd1Uuoe/ABKqnC/SLQjwAAAAAElFTkSuQmCC"},"images":{"fallback":{"src":"/mediabook/static/0693d20c86d8b096719ce9b9ba5c691b/5aead/cover.png","srcSet":"/mediabook/static/0693d20c86d8b096719ce9b9ba5c691b/e9fba/cover.png 50w,\n/mediabook/static/0693d20c86d8b096719ce9b9ba5c691b/15e42/cover.png 100w,\n/mediabook/static/0693d20c86d8b096719ce9b9ba5c691b/5aead/cover.png 200w,\n/mediabook/static/0693d20c86d8b096719ce9b9ba5c691b/d6138/cover.png 400w","sizes":"(min-width: 200px) 200px, 100vw"},"sources":[{"srcSet":"/mediabook/static/0693d20c86d8b096719ce9b9ba5c691b/b79cb/cover.avif 50w,\n/mediabook/static/0693d20c86d8b096719ce9b9ba5c691b/6d0de/cover.avif 100w,\n/mediabook/static/0693d20c86d8b096719ce9b9ba5c691b/f2685/cover.avif 200w,\n/mediabook/static/0693d20c86d8b096719ce9b9ba5c691b/4ff31/cover.avif 400w","type":"image/avif","sizes":"(min-width: 200px) 200px, 100vw"},{"srcSet":"/mediabook/static/0693d20c86d8b096719ce9b9ba5c691b/dbc4a/cover.webp 50w,\n/mediabook/static/0693d20c86d8b096719ce9b9ba5c691b/d8057/cover.webp 100w,\n/mediabook/static/0693d20c86d8b096719ce9b9ba5c691b/2e34e/cover.webp 200w,\n/mediabook/static/0693d20c86d8b096719ce9b9ba5c691b/416c3/cover.webp 400w","type":"image/webp","sizes":"(min-width: 200px) 200px, 100vw"}]},"width":200,"height":200}}},"pages":{"nodes":[{"id":"T0E6OlBhZ2UtMzU=","title":"Intro to Tip Calculator","slug":"intro-tip-calculator","sections":{"nodes":[{"id":"T0E6OlNlY3Rpb24tOTM=","title":"Intro to Tip Calculator","htmlContent":"<p>This is the second tutorial of Make School's iOS app tutorial series. In this tutorial, we'll learn core concepts for creating UI layouts by building a tip calculator.</p><h2>Why A Tip Calculator?</h2><p>In the US, it's customary to leave a tip for waiting staff like bartenders and waiters. An accepted range for the tip, also known as gratuity, is between 15% to 20% of your total bill.</p><p>Instead of having to do the math in your head, we'll build a simple tip calculator to calculate the tip for us.</p>"},{"id":"T0E6OlNlY3Rpb24tOTQ=","title":"Who Is This For?","htmlContent":"<p>iOS Beginners with a basic understanding of navigating and using Xcode. This tutorial will focus on building intermediate-level UI with <em>Interface Builder</em>.</p><h2>What You Should Already Know</h2><p>This tutorial builds on key concepts from the first Make School tutorial on building a <em>Magic 8-Ball</em>. You should have a understanding of the fundamentals of how to build simple iOS apps and how to navigate Xcode.</p><p>If you're a complete beginner and looking for your first introduction to iOS development, it's recommended to first complete the previous Make School tutorial on building a <em>Magic 8-Ball</em>.</p><h2>Estimated Completion Time:</h2><p>3 hours</p>"},{"id":"T0E6OlNlY3Rpb24tOTU=","title":"What We're Building","htmlContent":"<p>At the end of this tutorial, you'll have built your own tip calculator!</p><p><a href=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P0-intro/assets/light_flow.png\" target=\"_blank\">\n          <img src=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P0-intro/assets/light_flow.png\" alt=\"Light Flow\" title=\"\">\n        </a></p><p>Your tip calculator will be able to:</p><ol>\n<li>Enter a base bill amount to calculate your tip.</li>\n<li>Select a tip percentage of 15%, 18%, or 20%.</li>\n<li>Calculate the tip amount and total bill amount.</li>\n<li>Toggle the theme between light and dark mode.</li>\n<li>Clear and reset your tip calculator.</li>\n</ol>"},{"id":"T0E6OlNlY3Rpb24tOTY=","title":"What You'll Learn","htmlContent":"<p>By the end of this tutorial, you will:</p><ul>\n<li>visually breakdown designs into UI components</li>\n<li>learn about common UIKit objects</li>\n<li>use auto-layout and stack views to create dynamically re-sizing layouts</li>\n<li>configuring UI object properties programmatically</li>\n</ul>"},{"id":"T0E6OlNlY3Rpb24tOTc=","title":"If You Get Stuck","htmlContent":"<p>Getting stuck when coding (and debugging) is a natural part of the programming process. If you find yourself stuck on a problem or lost, pause for a moment and take a breath. Maybe take a walk. Then retrace your steps (in the tutorial, not the walk). Make sure you've follow each step of the tutorial. It's easy to make typos or to accidentally skip over important steps.</p><p>If you want to compare your code to the solution, you can find it here.</p><!-- TODO: insert link to github repo -->"}]},"next":{"id":"T0E6OlBhZ2UtMzY=","slug":"design-breakdown","title":"Design Breakdown"},"previous":{"id":"T0E6OlBhZ2UtMzY=","slug":"design-breakdown","title":"Design Breakdown"}},{"id":"T0E6OlBhZ2UtMzY=","title":"Design Breakdown","slug":"design-breakdown","sections":{"nodes":[{"id":"T0E6OlNlY3Rpb24tOTg=","title":"Design Breakdown","htmlContent":"<p>Before we jump into Xcode, we'll first take some time to review and breakdown our tip calculator design. We'll learn to visually break apart designs into smaller chunks that we can code one at a time.</p><p><a href=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P1-Design-Breakdown/assets/design_breakdown.png\" target=\"_blank\">\n          <img src=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P1-Design-Breakdown/assets/design_breakdown.png\" alt=\"Design Breakdown\" title=\"\">\n        </a></p><div class=\"info\">\n<p>\nIn this tutorial, we'll often refer to the terms <em>UI</em> (user interface) and <em>view</em>. Both terms refer to building the app's user interface, or the visual elements on the screen that the user interacts with.</p>\n</div>"},{"id":"T0E6OlNlY3Rpb24tOTk=","title":"Reviewing Our Design","htmlContent":"<p>Let's take another look at the designs for the tip calculator app that we're going to build:</p><p><a href=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P1-Design-Breakdown/assets/light_flow.png\" target=\"_blank\">\n          <img src=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P1-Design-Breakdown/assets/light_flow.png\" alt=\"Light Flow\" title=\"\">\n        </a></p><p>Listing the steps for each screen above (left to right):</p><ol>\n<li>Empty state when a user first opens the app or taps the reset button.</li>\n<li>User inputs a bill amount into bill amount field using the iOS keyboard.</li>\n<li>After hitting the <em>Calculate</em> button or selecting a tip percentage, dismiss the keyboard and show the tip amount and total bill amount.</li>\n</ol><p>The user also can toggle the app's color theme from light-mode to dark-mode using the switch in the top-right corner. In dark-mode, our tip calculator will look like:</p><p><a href=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P1-Design-Breakdown/assets/dark_flow.png\" target=\"_blank\">\n          <img src=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P1-Design-Breakdown/assets/dark_flow.png\" alt=\"Dark Flow\" title=\"\">\n        </a></p><p>We've reviewed our app designs. Next, let's learn to visually breakdown our design into smaller parts.</p>"},{"id":"T0E6OlNlY3Rpb24tMTAw","title":"Design Breakdown","htmlContent":"<p>Implementing an app design without any planning can be overwhelming. It's hard to know where to start.</p><p>Instead, let's take our designs and visually break down elements into smaller groups that we can implement one at a time.</p><p><a href=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P1-Design-Breakdown/assets/design_breakdown_groups.png\" target=\"_blank\">\n          <img src=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P1-Design-Breakdown/assets/design_breakdown_groups.png\" alt=\"Design Breakdown Groups\" title=\"\">\n        </a></p><p>If you're doing this process on your own, it's helpful to use pen and paper.</p><p>At this point, you might be thinking, \"Why did we group each of the UI elements in the way we did?\" Why not any of the other following options?</p><p><a href=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P1-Design-Breakdown/assets/alternate_ui_groups.png\" target=\"_blank\">\n          <img src=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P1-Design-Breakdown/assets/alternate_ui_groups.png\" alt=\"Other Grouping Options\" title=\"\">\n        </a></p><p>To answer this question, we'll have to learn about the basic UI building block, <em>UIView</em>.</p><h2>What Is A UIView?</h2><p>The <em>UIView</em> class is an object that represents a rectangular area on your iPhone screen. Your entire UI (with few exceptions), is built from multiple <em>UIView</em> objects.</p><p>To better understand this, let's take a look at Square Cash, an app that allows you to send and receive money.</p><p><a href=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P1-Design-Breakdown/assets/square_cash_uiviews.png\" target=\"_blank\">\n          <img src=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P1-Design-Breakdown/assets/square_cash_uiviews.png\" alt=\"Square Cash UIView Breakdown\" title=\"\">\n        </a></p><p>As you can see, the whole screen has a base <code>UIView</code> (blue color) that we've named the root view. This will usually be the root view of the respective active <code>UIViewController</code>.</p><p>On top of the root, you can add subviews. These subviews are <code>UIView</code> objects or <code>UIView</code> subclasses. In the <em>Square Cash</em> app, the UI consists of buttons and labels but there are many other type of UI objects <code>UIKit</code> provides.</p><div class=\"info\">\n<p>\n<strong>What is UIKit?</strong></p>\n\n<p><code>UIKit</code> is a framework that provides pre-built objects and functionality that you can use to build iOS apps. This includes a lot of under-the-hood functionality (handling your app's lifecycle and resource management) as well as commonly used UI components (buttons and labels).</p>\n</div><!-- break --><div class=\"challenge\">\n<p>\nIdentify each of the <code>UIView</code> objects in the tip calculator design. You can reference the design below:</p>\n\n<p><a href=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P1-Design-Breakdown/assets/tc_design_reference.png\" target=\"_blank\">\n          <img src=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P1-Design-Breakdown/assets/tc_design_reference.png\" alt=\"Tip Calculator Design\" title=\"\">\n        </a></p>\n</div><!-- break --><div class=\"solution\">\n<p>\nIf you break down the tip calculator design into it's individual subviews you should get the following:</p>\n\n<p><a href=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P1-Design-Breakdown/assets/tc_view_breakdown.png\" target=\"_blank\">\n          <img src=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P1-Design-Breakdown/assets/tc_view_breakdown.png\" alt=\"Tip Calculator View Breakdown\" title=\"\">\n        </a></p>\n\n<p>You'll notice many new UI components that we're using from UIKit. Each of these UI objects either are or inherit from <code>UIView</code>. We'll formally introduce each of these UI objects later in this tutorial.</p>\n</div><h2>Grouping Subviews</h2><p>It's common to organize our subviews in groups. Although you can technically group subviews however you'd like, usually groups are based on how you plan to position and layout your UI (more on this later).</p><p>Using our <em>Square Cash</em> example, you might group each of the subviews in the following manner:</p><p><a href=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P1-Design-Breakdown/assets/square_cash_groups.png\" target=\"_blank\">\n          <img src=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P1-Design-Breakdown/assets/square_cash_groups.png\" alt=\"Square Cash Groups\" title=\"\">\n        </a></p><p>This makes it easier to re-position entire groups of views. i.e. repositioning the entire header up or down a few pixels</p><p>Let's apply the steps we just took with the <em>Square Cash</em> app to our own tip calculator design.</p><div class=\"challenge\">\n<p>\nGroup each of the view elements together using where you left off from the previous challenge. Check your answer in the solution when you're done. You can reference the design below:</p>\n\n<p><a href=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P1-Design-Breakdown/assets/tc_design_reference.png\" target=\"_blank\">\n          <img src=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P1-Design-Breakdown/assets/tc_design_reference.png\" alt=\"Tip Calculator Design\" title=\"\">\n        </a></p>\n</div><!-- break  --><div class=\"solution\">\n<p>\nYou should have grouped each of the individual view objects from the previous challenge as follows:</p>\n\n<p><a href=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P1-Design-Breakdown/assets/tc_view_grouped.png\" target=\"_blank\">\n          <img src=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P1-Design-Breakdown/assets/tc_view_grouped.png\" alt=\"Tip Calculator View Grouped\" title=\"\">\n        </a></p>\n</div><!-- TODO: better explanation of how we grouped these elements together -->"},{"id":"T0E6OlNlY3Rpb24tMTAx","title":"Introducing UI Objects From UIKit","htmlContent":"<p>In the previous section we identified each of the UIView objects and grouped them into 4 main groups:</p><ol>\n<li>Header - displays app title and theme switch</li>\n<li>Tip Input - provides UI elements for user input</li>\n<li>Tip Output - displays output of tip calculator</li>\n<li>Reset Button - resets calculator to starting state</li>\n</ol><p>Now, we'll go through and introduce all of the UI components we'll use from UIKit. These UI objects are meant to be basic building blocks to create your app's UI.</p><h2>Header</h2><p>The header is a custom view on the view controller's root view.</p><p><a href=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P1-Design-Breakdown/assets/header_overview.png\" target=\"_blank\">\n          <img src=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P1-Design-Breakdown/assets/header_overview.png\" alt=\"Header Overview\" title=\"\">\n        </a></p><p>As you can see, the header is a <code>UIView</code> placed on top of the root view. Additionally, it has two subviews place on top of the header view itself: a label and switch.</p><h3>UILabel</h3><p><code>UILabel</code> directly subclasses <code>UIView</code> and is used to display text on the iOS device's screen.</p><p><a href=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P1-Design-Breakdown/assets/header_title_label.png\" target=\"_blank\">\n          <img src=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P1-Design-Breakdown/assets/header_title_label.png\" alt=\"Header Title Label\" title=\"\">\n        </a></p><p>The <code>UILabel</code> class can be configured from it's many properties. (i.e. text, font, text color, number of lines, etc).</p><!-- In our case, we'll use an off-black (#4A4A4A) text color and bold font weight of `San Francisco`, the default system font created by Apple. --><p>In our case, we use this label to display title text for our tip calculator app.</p><h3>UISwitch</h3><p>The <code>UISwitch</code> object is a subclass of <code>UIControl</code>, which is a subclass of <code>UIView</code>.</p><pre><span class=\"k\">class</span> <span class=\"nc\">UISwitch</span> <span class=\"p\">:</span> <span class=\"n\">UIControl</span><span class=\"p\">,</span> <span class=\"n\">NSCoding</span> <span class=\"p\">{</span> <span class=\"o\">...</span> <span class=\"p\">}</span>\n\n<span class=\"k\">class</span> <span class=\"nc\">UIControl</span> <span class=\"p\">:</span> <span class=\"n\">UIView</span> <span class=\"p\">{</span> <span class=\"o\">...</span> <span class=\"p\">}</span>\n</pre><p>All UI objects that we'll use from <code>UIKit</code> will inherit from the <code>UIView</code> class.</p><p>A switch is the default UI component for toggling between an on and off state. You can think of it as the iOS version of a light switch.</p><p><a href=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P1-Design-Breakdown/assets/header_switch.png\" target=\"_blank\">\n          <img src=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P1-Design-Breakdown/assets/header_switch.png\" alt=\"Header Switch\" title=\"\">\n        </a></p><p>When toggled on, the switch will change the color theme of the app from light to dark.</p><p><a href=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P1-Design-Breakdown/assets/header_dark.png\" target=\"_blank\">\n          <img src=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P1-Design-Breakdown/assets/header_dark.png\" alt=\"Header Dark Theme\" title=\"\">\n        </a></p><h2>Tip Input</h2><p>The next group of views allows the user to provide input to calculate the bill amount and tip percentage for the bill.</p><p><a href=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P1-Design-Breakdown/assets/tip_input_outline.png\" target=\"_blank\">\n          <img src=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P1-Design-Breakdown/assets/tip_input_outline.png\" alt=\"Tip Input Outline\" title=\"\">\n        </a></p><p>As with the header view, we'll break down this group of UI components into its individual components.</p><h3>UILabel</h3><p>We've already covered the <code>UILabel</code> class, so we won't cover it again.</p><div class=\"challenge\">\n<p>\nIdentify the <code>UILabel</code>(s) objects on the tip input card view.</p>\n</div><!-- break --><div class=\"solution\">\n<p>\nBoth labels are on the left-side on the tip input card view: <a href=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P1-Design-Breakdown/assets/tip_input_labels.png\" target=\"_blank\">\n          <img src=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P1-Design-Breakdown/assets/tip_input_labels.png\" alt=\"Input Title Labels\" title=\"\">\n        </a></p>\n</div><h3>UITextField</h3><p>The <code>UITextField</code> provides a text field where the user can input text with the iOS keyboard.</p><p><a href=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P1-Design-Breakdown/assets/tip_input_text_field.png\" target=\"_blank\">\n          <img src=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P1-Design-Breakdown/assets/tip_input_text_field.png\" alt=\"Tip Input Text Field\" title=\"\">\n        </a></p><p>When a user taps a text field, the text field will become active (referred to as the first responder) and the device keyboard will appear.</p><p><a href=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P1-Design-Breakdown/assets/tc_active_text_field.png\" target=\"_blank\">\n          <img src=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P1-Design-Breakdown/assets/tc_active_text_field.png\" alt=\"Active Text Field\" title=\"\">\n        </a></p><p>We'll need the text field for the user to input their bill amount.</p><h3>UISegmentedControl</h3><p>Similar to the switch, the <code>UISegmentedControl</code> class provides a UI object that allows the user to toggle between different options. The main different being that a segmented control can have 2+ different states, while a switch can only toggle in-between an on and off state.</p><p>In addition to 2+ toggle states, switches can also have each option name labeled. Let's take a look at the segmented control we'll use in our tip calculator.</p><p><a href=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P1-Design-Breakdown/assets/tip_input_segmented_control.png\" target=\"_blank\">\n          <img src=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P1-Design-Breakdown/assets/tip_input_segmented_control.png\" alt=\"Tip Percentage Segmented Control\" title=\"\">\n        </a></p><p>Our tip calculator will need a segmented control so that the user can choose the tip percentage they want to use for calculating gratuity.</p><h2>Tip Output</h2><p>The tip output group provides the output tip amount and total bill amount of the tip calculator.</p><p><a href=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P1-Design-Breakdown/assets/tc_output_outline.png\" target=\"_blank\">\n          <img src=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P1-Design-Breakdown/assets/tc_output_outline.png\" alt=\"Output Outline\" title=\"\">\n        </a></p><p>We've already introduced all of the UI objects in this group.</p><div class=\"challenge\">\n<p>\nIdentify all of the different UIKit objects in the tip output group.</p>\n</div><!-- break --><div class=\"solution\">\n<p>\nThe entire tip output group is made up of a card view that is a <code>UIView</code> with 4 <code>UILabel</code> for each respective title and amount.</p>\n\n<p><a href=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P1-Design-Breakdown/assets/tip_output_views.png\" target=\"_blank\">\n          <img src=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P1-Design-Breakdown/assets/tip_output_views.png\" alt=\"Tip Output Views\" title=\"\">\n        </a></p>\n</div><h2>Reset Button</h2><p>Next, we'll introduce the last UIKit object that we'll need for our tip calculator: <code>UIButton</code>.</p><p><a href=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P1-Design-Breakdown/assets/tc_reset_outline.png\" target=\"_blank\">\n          <img src=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P1-Design-Breakdown/assets/tc_reset_outline.png\" alt=\"Reset Outline\" title=\"\">\n        </a></p><p>Simple enough, this grouping will consist only of a single element: a button.</p><h3>UIButton</h3><p>The <code>UIButton</code>, along with labels, is one of the most common objects for building your UI. A user can interact with a button by tapping it and triggering an event. This event can be tied to calling a function and running code.</p><p><a href=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P1-Design-Breakdown/assets/reset_button.png\" target=\"_blank\">\n          <img src=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P1-Design-Breakdown/assets/reset_button.png\" alt=\"Reset Button\" title=\"\">\n        </a></p><p>Our reset button will allow a user to clear the current input from our tip calculator and reset it to an empty state.</p><div class=\"info\">\n<p>\nYou don't need to memorize all of the UIKit objects we've just covered. Just remember that there are pre-made UI components that you can use to build your UI. If you're trying to build any type of visual element, check <code>UIKit</code> to see if there's a base UI object you can use to build off of.</p>\n</div>"},{"id":"T0E6OlNlY3Rpb24tMTAy","title":"Reviewing What We've Learning","htmlContent":"<p>We've reviewed and learned about many new UI objects in <code>UIKit</code>. You'll use these objects as basic building blocks for creating various UI for your app. If you're ever looking for a comprehensive guide of all of the UIKit objects, you can reference Apple's developer docs by <a href=\"https://developer.apple.com/documentation/uikit/views_and_controls\" target=\"_blank\">clicking here</a>.</p><p>Moving forward, we'll start building tip calculator in Xcode and look at how to use each of these UI components.</p>"}]},"next":{"id":"T0E6OlBhZ2UtMzc=","slug":"getting-started","title":"Getting-Started"},"previous":{"id":"T0E6OlBhZ2UtMzc=","slug":"getting-started","title":"Getting-Started"}},{"id":"T0E6OlBhZ2UtMzc=","title":"Getting-Started","slug":"getting-started","sections":{"nodes":[{"id":"T0E6OlNlY3Rpb24tMTAz","title":"Getting-Started","htmlContent":"<p>In this section, we'll get introduced to our new Xcode project and start working on implementing our tip calculator design.</p><p>We'll get started by downloading a Xcode starter project. You can download the <code>.zip</code> file by <a href=\"https://github.com/ocwang/TipCalculatorStarter/archive/master.zip\" target=\"_blank\">clicking here.</a></p>"},{"id":"T0E6OlNlY3Rpb24tMTA0","title":"In Your Starter Project","htmlContent":"<p>After downloading the starter project, open the project in Xcode. You should see something the following:</p><p><a href=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P2-Getting-Started/assets/open_starter_project.png\" target=\"_blank\">\n          <img src=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P2-Getting-Started/assets/open_starter_project.png\" alt=\"Open Starter Project\" title=\"\">\n        </a></p><p>Build and run the current starter project in a simulator or iPhone device of your choice.</p><div class=\"action\">\n<p>\nRun the new starter project to make sure there are no compilation errors. If all goes well, your project should run successfully and display an empty white screen (we haven't built anything yet!)</p>\n\n<p><a href=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P2-Getting-Started/assets/white_screen.png\" target=\"_blank\">\n          <img src=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P2-Getting-Started/assets/white_screen.png\" alt=\"Empty Screen\" title=\"\">\n        </a></p>\n</div><h2>Addressing Possible Warnings</h2><div class=\"action\">\n<p>\nAlternatively, if you have a few warnings pop up (which can happen as XCode and Swift are constantly growing, changing, and updating), you can move forward with clicking the <strong>Perform Changes</strong> button. </p>\n\n<p><a href=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P2-Getting-Started/assets/00_build_warnings.png\" target=\"_blank\">\n          <img src=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P2-Getting-Started/assets/00_build_warnings.png\" alt=\"Build Warnings\" title=\"\">\n        </a></p>\n\n<p>[action]\nYou may also have a warning to convert the starter project to the latest Swift version. The warning will look similar to the following. Feel free to move forward with the update. </p>\n\n<p><a href=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P2-Getting-Started/assets/01_conversion_warning.png\" target=\"_blank\">\n          <img src=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P2-Getting-Started/assets/01_conversion_warning.png\" alt=\"Build Warnings\" title=\"\">\n        </a>\nWrap up by saving the changes! \n<a href=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P2-Getting-Started/assets/03_finish_warnings.png\" target=\"_blank\">\n          <img src=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P2-Getting-Started/assets/03_finish_warnings.png\" alt=\"Build Warnings\" title=\"\">\n        </a></p>\n</div><p>Next, let's take a look inside our starter project.</p><h2>View Controller</h2><!-- TODO: considering adding a section about directory layout? --><p>First, we'll start with our view controller.</p><div class=\"action\">\n<p>\nUsing the <em>Project Navigator</em>, open the <code>ViewController.swift</code> source file. You should see the following code:</p>\n<pre><span class=\"kd\">class</span> <span class=\"nc\">ViewController</span><span class=\"p\">:</span> <span class=\"bp\">UIViewController</span> <span class=\"p\">{</span>\n\n    <span class=\"c1\">// </span><span class=\"cs\">MARK:</span><span class=\"c1\"> - View Lifecycle</span>\n\n    <span class=\"kr\">override</span> <span class=\"kd\">func</span> <span class=\"nf\">viewDidLoad</span><span class=\"p\">()</span> <span class=\"p\">{</span>\n        <span class=\"kc\">super</span><span class=\"p\">.</span><span class=\"n\">viewDidLoad</span><span class=\"p\">()</span>\n    <span class=\"p\">}</span>\n<span class=\"p\">}</span>\n</pre>\n</div><p>Just boilerplate code, nothing is happening yet. We'll eventually write our tip calculator logic in here later.</p><h2>Main Storyboard</h2><p>Let's move onto our storyboard.</p><div class=\"action\">\n<p>\nOpen <code>Main.storyboard</code> from your <em>Project Navigator</em>. You'll see the following:</p>\n\n<p><a href=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P2-Getting-Started/assets/starting_storyboard.png\" target=\"_blank\">\n          <img src=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P2-Getting-Started/assets/starting_storyboard.png\" alt=\"Starting Storyboard\" title=\"\">\n        </a></p>\n</div><p>Right now there's an empty, white view controller. (The one we saw in our simulator remember?)</p><p>Let's review how our storyboard view controller is connected to our <code>.swift</code> file.</p><div class=\"action\">\n<p>\nClick on the view controller representation in your storyboard. With your storyboard view controller selected, navigate to the <em>Class Inspector</em> in the <em>Utilities area</em>.</p>\n\n<p>You'll notice that the <code>ViewController.swift</code> source code is paired with the View Controller object in your <code>Main.storyboard</code>.</p>\n\n<p><a href=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P2-Getting-Started/assets/storyboard_vc_class.png\" target=\"_blank\">\n          <img src=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P2-Getting-Started/assets/storyboard_vc_class.png\" alt=\"Storyboard View Controller Class\" title=\"\">\n        </a></p>\n</div><p>Next we'll take a look at our project's assets.</p><h2>XCAssets</h2><p>Your project assets contain your media: images, movies, app icons, etc.</p><div class=\"action\">\n<p>\nOpen <code>Assets.xcassets</code> to see your project assets. <a href=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P2-Getting-Started/assets/project_assets.png\" target=\"_blank\">\n          <img src=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P2-Getting-Started/assets/project_assets.png\" alt=\"Project Assets\" title=\"\">\n        </a></p>\n</div><p>In your asset catalog, you should see an app icon that's already set for you and two folders containing pre-defined color sets for the different color themes we'll implement later.</p><p>To pair with our custom colors in our asset catalog, your project also contains a <code>UIColor</code> extension that allows you to access each of the app's colors through code.</p><div class=\"action\">\n<p>\nOpen <code>UIColor+TC.swift</code> from your <em>Project Navigator</em>. If you don't see it, you'll have to expand the <code>Supporting Files</code> folder in your <em>Project Navigator</em>. You should see the following:</p>\n<pre><span class=\"kr\">import</span> <span class=\"nx\">UIKit</span><span class=\"p\">.</span><span class=\"nx\">UIColor</span>\n\n<span class=\"nx\">extension</span> <span class=\"nx\">UIColor</span> <span class=\"p\">{</span>\n\n    <span class=\"c1\">// MARK: Theme Colors</span>\n\n    <span class=\"kr\">static</span> <span class=\"kd\">var</span> <span class=\"nx\">tcDarkBlue</span><span class=\"o\">:</span> <span class=\"nx\">UIColor</span> <span class=\"p\">{</span>\n        <span class=\"k\">return</span> <span class=\"nx\">UIColor</span><span class=\"p\">(</span><span class=\"nx\">named</span><span class=\"o\">:</span> <span class=\"s2\">\"tcDarkBlue\"</span><span class=\"p\">)</span><span class=\"o\">!</span>\n    <span class=\"p\">}</span>\n\n    <span class=\"kr\">static</span> <span class=\"kd\">var</span> <span class=\"nx\">tcOffWhite</span><span class=\"o\">:</span> <span class=\"nx\">UIColor</span> <span class=\"p\">{</span>\n        <span class=\"k\">return</span> <span class=\"nx\">UIColor</span><span class=\"p\">(</span><span class=\"nx\">named</span><span class=\"o\">:</span> <span class=\"s2\">\"tcOffWhite\"</span><span class=\"p\">)</span><span class=\"o\">!</span>\n    <span class=\"p\">}</span>\n\n    <span class=\"kr\">static</span> <span class=\"kd\">var</span> <span class=\"nx\">tcHotPink</span><span class=\"o\">:</span> <span class=\"nx\">UIColor</span> <span class=\"p\">{</span>\n        <span class=\"k\">return</span> <span class=\"nx\">UIColor</span><span class=\"p\">(</span><span class=\"nx\">named</span><span class=\"o\">:</span> <span class=\"s2\">\"tcHotPink\"</span><span class=\"p\">)</span><span class=\"o\">!</span>\n    <span class=\"p\">}</span>\n\n    <span class=\"kr\">static</span> <span class=\"kd\">var</span> <span class=\"nx\">tcCharcoal</span><span class=\"o\">:</span> <span class=\"nx\">UIColor</span> <span class=\"p\">{</span>\n        <span class=\"k\">return</span> <span class=\"nx\">UIColor</span><span class=\"p\">(</span><span class=\"nx\">named</span><span class=\"o\">:</span> <span class=\"s2\">\"tcCharcoal\"</span><span class=\"p\">)</span><span class=\"o\">!</span>\n    <span class=\"p\">}</span>\n\n    <span class=\"kr\">static</span> <span class=\"kd\">var</span> <span class=\"nx\">tcAlmostBlack</span><span class=\"o\">:</span> <span class=\"nx\">UIColor</span> <span class=\"p\">{</span>\n        <span class=\"k\">return</span> <span class=\"nx\">UIColor</span><span class=\"p\">(</span><span class=\"nx\">named</span><span class=\"o\">:</span> <span class=\"s2\">\"tcAlmostBlack\"</span><span class=\"p\">)</span><span class=\"o\">!</span>\n    <span class=\"p\">}</span>\n\n    <span class=\"kr\">static</span> <span class=\"kd\">var</span> <span class=\"nx\">tcMediumBlack</span><span class=\"o\">:</span> <span class=\"nx\">UIColor</span> <span class=\"p\">{</span>\n        <span class=\"k\">return</span> <span class=\"nx\">UIColor</span><span class=\"p\">(</span><span class=\"nx\">named</span><span class=\"o\">:</span> <span class=\"s2\">\"tcMediumBlack\"</span><span class=\"p\">)</span><span class=\"o\">!</span>\n    <span class=\"p\">}</span>\n\n    <span class=\"kr\">static</span> <span class=\"kd\">var</span> <span class=\"nx\">tcBlueBlack</span><span class=\"o\">:</span> <span class=\"nx\">UIColor</span> <span class=\"p\">{</span>\n        <span class=\"k\">return</span> <span class=\"nx\">UIColor</span><span class=\"p\">(</span><span class=\"nx\">named</span><span class=\"o\">:</span> <span class=\"s2\">\"tcBlueBlack\"</span><span class=\"p\">)</span><span class=\"o\">!</span>\n    <span class=\"p\">}</span>\n\n    <span class=\"kr\">static</span> <span class=\"kd\">var</span> <span class=\"nx\">tcSeafoamGreen</span><span class=\"o\">:</span> <span class=\"nx\">UIColor</span> <span class=\"p\">{</span>\n        <span class=\"k\">return</span> <span class=\"nx\">UIColor</span><span class=\"p\">(</span><span class=\"nx\">named</span><span class=\"o\">:</span> <span class=\"s2\">\"tcSeafoamGreen\"</span><span class=\"p\">)</span><span class=\"o\">!</span>\n    <span class=\"p\">}</span>\n\n    <span class=\"kr\">static</span> <span class=\"kd\">var</span> <span class=\"nx\">tcBlack</span><span class=\"o\">:</span> <span class=\"nx\">UIColor</span> <span class=\"p\">{</span>\n        <span class=\"k\">return</span> <span class=\"nx\">UIColor</span><span class=\"p\">(</span><span class=\"nx\">named</span><span class=\"o\">:</span> <span class=\"s2\">\"tcBlack\"</span><span class=\"p\">)</span><span class=\"o\">!</span>\n    <span class=\"p\">}</span>\n\n    <span class=\"kr\">static</span> <span class=\"kd\">var</span> <span class=\"nx\">tcWhite</span><span class=\"o\">:</span> <span class=\"nx\">UIColor</span> <span class=\"p\">{</span>\n        <span class=\"k\">return</span> <span class=\"nx\">UIColor</span><span class=\"p\">(</span><span class=\"nx\">named</span><span class=\"o\">:</span> <span class=\"s2\">\"tcWhite\"</span><span class=\"p\">)</span><span class=\"o\">!</span>\n    <span class=\"p\">}</span>\n<span class=\"p\">}</span>\n</pre>\n</div><p>This file pairs each of the class variables to the custom color sets defined in our asset catalog.</p><p>Once we start coding, we'll be able to access each respective color through the <code>UIColor</code> class variable:</p><pre><span class=\"kd\">let</span> <span class=\"nv\">selectedColor</span> <span class=\"p\">=</span> <span class=\"bp\">UIColor</span><span class=\"p\">.</span><span class=\"n\">tcSeafoamGreen</span>\n</pre><p>Notice that we prefix each of our custom colors with <code>tc</code> to avoid namespace conflicts and make our colors easier to find with Xcode autocomplete.</p><div class=\"info\">\n<p>\nIn this project, your custom colors have been defined in your asset catalog, however this is just one of many ways for defining custom colors. You can also create custom colors programmatically or through <em>Interface Builder</em>.</p>\n</div><h2>App Delegate</h2><p>To wrap up our new project tour, let's briefly take a look at our <em>App Delegate</em>.</p><div class=\"action\">\n<p>\nOpen <code>AppDelegate.swift</code> from your project navigator:</p>\n<pre><span class=\"kr\">import</span> <span class=\"nx\">UIKit</span>\n\n<span class=\"err\">@</span><span class=\"nx\">UIApplicationMain</span>\n<span class=\"kr\">class</span> <span class=\"nx\">AppDelegate</span><span class=\"o\">:</span> <span class=\"nx\">UIResponder</span><span class=\"p\">,</span> <span class=\"nx\">UIApplicationDelegate</span> <span class=\"p\">{</span>\n\n    <span class=\"kd\">var</span> <span class=\"nb\">window</span><span class=\"o\">:</span> <span class=\"nx\">UIWindow</span><span class=\"o\">?</span>\n\n    <span class=\"c1\">// MARK: - App Lifecycle</span>\n\n    <span class=\"nx\">func</span> <span class=\"nx\">application</span><span class=\"p\">(</span><span class=\"nx\">_</span> <span class=\"nx\">application</span><span class=\"o\">:</span> <span class=\"nx\">UIApplication</span><span class=\"p\">,</span> <span class=\"nx\">didFinishLaunchingWithOptions</span> <span class=\"nx\">launchOptions</span><span class=\"o\">:</span> <span class=\"p\">[</span><span class=\"nx\">UIApplicationLaunchOptionsKey</span><span class=\"o\">:</span> <span class=\"nx\">Any</span><span class=\"p\">]</span><span class=\"o\">?</span><span class=\"p\">)</span> <span class=\"o\">-&gt;</span> <span class=\"nx\">Bool</span> <span class=\"p\">{</span>\n        <span class=\"c1\">// Override point for customization after application launch.</span>\n        <span class=\"k\">return</span> <span class=\"kc\">true</span>\n    <span class=\"p\">}</span>\n<span class=\"p\">}</span>\n</pre>\n</div><!-- break --><div class=\"info\">\n<p>\nFor this tutorial, you won't need to change or modify the <em>App Delegate</em>. However, it's helpful to know about it's purpose for when you start writing your own apps.</p>\n</div><p>Each iOS Xcode project must have an <code>AppDelegate.swift</code> file which is responsible for the app's lifecycle. The app delegate specifies what happens when app lifecycle events are triggered. Common example events are app launch, receiving a push notification, app termination, etc.</p><p>In our tip calculator's app delegate, we don't add any code other than the boilerplate <code>application(_:didFinishLaunchingWithOptions:)</code> method that comes by default in each Xcode project template.</p><h2>Wrapping Up</h2><p>We've just taken a look at the files in our new Xcode starter project. Throughout this tutorial, we'll continue to build on this project to create our final tip calculator.</p><p>Let's get started by diving into storyboard and creating our views for our UI.</p>"}]},"next":{"id":"T0E6OlBhZ2UtMzg=","slug":"ui-layout","title":"UI Layout"},"previous":{"id":"T0E6OlBhZ2UtMzg=","slug":"ui-layout","title":"UI Layout"}},{"id":"T0E6OlBhZ2UtMzg=","title":"UI Layout","slug":"ui-layout","sections":{"nodes":[{"id":"T0E6OlNlY3Rpb24tMTA1","title":"UI Layout","htmlContent":"<p>We'll start building our app by implementing the UI in <em>Interface Builder</em>. For reference, here are the tip calculator designs:</p><p><a href=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P3-UI-Layout/assets/tc_view_breakdown.png\" target=\"_blank\">\n          <img src=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P3-UI-Layout/assets/tc_view_breakdown.png\" alt=\"Design Breakdown\" title=\"\">\n        </a></p>"},{"id":"T0E6OlNlY3Rpb24tMTA2","title":"Creating Views","htmlContent":"<p>We'll get started by creating our header view with a <code>UIView</code>.</p><div class=\"info\">\n<p>\n<code>UIKit</code> has it's own header-like bar called the <code>UINavigationBar</code>. To keep things simple, we'll start from scratch and create our own header view instead of using iOS's <code>UINavigationBar</code>.</p>\n</div><!-- break --><div class=\"action\">\n<p>\nOpen <code>Main.storyboard</code> from your project navigator. You should see your single view controller. <a href=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P3-UI-Layout/assets/starting_storyboard.png\" target=\"_blank\">\n          <img src=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P3-UI-Layout/assets/starting_storyboard.png\" alt=\"Starting Storyboard\" title=\"\">\n        </a></p>\n</div><p>Next, we'll add a <code>UIView</code> and reposition/resize it to be our header view.</p><div class=\"action\">\n<p>\nCreate a header view by dragging an <code>UIView</code> object from the <em>Object Library</em> to the top of the view controller. Don't worry too much about the perfect size and position for now. We'll handle that later.</p>\n\n<p><video width=\"100%\" controls><source src=\"https://s3.amazonaws.com/mgwu-misc/Tip+Calculator+Swift+4/p3_ui_layout/add_custom_nav_bar.mp4\" type=\"video/mp4\"></source></video></p>\n</div><p>The new <code>UIView</code> object that we just added is going to be our custom header view. We'll add other subviews onto it later.</p><p>You might notice, that our header view is a little hard to see because it's the same color as the view controller's root view: white. Let's change the color of our root view to add some contrast.</p><div class=\"action\">\n<p>\nChange the view controller's root view to off-white:</p>\n\n<ol>\n<li>Select the view controller's root view by either clicking on it in your storyboard or selecting it in the document outline. If you don't see it in the <em>Document Outline</em>, you might have to expand the <code>View Controller Scene</code> tree. Make sure you're not selecting the header view by accident. <a href=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P3-UI-Layout/assets/select_root_view.png\" target=\"_blank\">\n          <img src=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P3-UI-Layout/assets/select_root_view.png\" alt=\"Select Root View\" title=\"\">\n        </a>\n</li>\n<li>With the root view still selected, open the <em>Attributes Inspector</em> in the <em>Utilities area</em>. <a href=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P3-UI-Layout/assets/open_attributes_inspector.png\" target=\"_blank\">\n          <img src=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P3-UI-Layout/assets/open_attributes_inspector.png\" alt=\"Open Attributes Inspector\" title=\"\">\n        </a>\n</li>\n<li>Next, click on the blue dropdown button beside the active color for the <code>Background Color</code> field. <a href=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P3-UI-Layout/assets/click_bg_color_dropdown.png\" target=\"_blank\">\n          <img src=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P3-UI-Layout/assets/click_bg_color_dropdown.png\" alt=\"Click Background Color Dropdown\" title=\"\">\n        </a>\n</li>\n<li>Finally, select the <code>Off-White</code> color under the <em>Named Colors</em> subheader in the dropdown menu. <a href=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P3-UI-Layout/assets/select_off_white.png\" target=\"_blank\">\n          <img src=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P3-UI-Layout/assets/select_off_white.png\" alt=\"Select Off-White Background Color\" title=\"\">\n        </a>\n</li>\n</ol>\n</div><p>We've changed the <em>background color</em> attribute of the root view to a different color. The <code>Off White</code> color we chose was pre-defined in our <code>Assets.xcasset</code> asset catalog.</p><p>Before we add more views or configure more properties, let's learn about the iOS coordinate system and the frame attribute of <code>UIView</code> and it's subclasses. We'll need to learn about the iOS coordinate system to properly position and size our views.</p>"},{"id":"T0E6OlNlY3Rpb24tMTA3","title":"iOS Coordinate System","htmlContent":"<p>You can think of your phone screen as a coordinate system with it's origin in the top-left corner.</p><p><a href=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P3-UI-Layout/assets/ios_coord_system.png\" target=\"_blank\">\n          <img src=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P3-UI-Layout/assets/ios_coord_system.png\" alt=\"iOS Coordinate System\" title=\"\">\n        </a></p><p>As we've previously discussed, view can be represented as rectangles drawn on our device's screen. This rectangle can be represented by it's starting point (top-left corner of the rectangle) along with it's size (width and height). Let's look at an example:</p><p><a href=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P3-UI-Layout/assets/coord_example.png\" target=\"_blank\">\n          <img src=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P3-UI-Layout/assets/coord_example.png\" alt=\"Coord Example\" title=\"\">\n        </a></p><!-- break --><div class=\"challenge\">\n<p>\nIn the image above, what is the red view's starting point? What about it's size?</p>\n</div><!-- break --><div class=\"solution\">\n<p>\nAs you can see from the numbered X and Y axis, the view rectangle starts at the point (27, 48) in the iOS coordinate system and has a width of 50pts and a height of 35pts.</p>\n</div><p>In Swift, we have the <code>CGPoint</code> and <code>CGSize</code> data types to represent coordinate points and sizes respectively. A <code>CGPoint</code> value is a pair of X and Y values. A <code>CGSize</code> value is a pair of width and height values.</p><p>Additionally, these two data types can be combined into <code>CGRect</code> data type (X, Y, width, height) that represents a rectangle represented by it's point and size properties.</p><p>Each <code>UIView</code> has a property called it's <code>frame</code> of type <code>CGRect</code>. You can use each view's frame property to manipulate it's position and size.</p><div class=\"info\">\n<p>\nAt some point, you'll come across another view property named <code>bounds</code> that's also a <code>CGRect</code>. The <code>frame</code> of a view represents the view's rectangle in it's super view's coordinate system while it's <code>bound</code> property refers to the rectangle using the view's top-left corner as the origin of it's coordinate system. In other words, the <code>bounds</code> property of a view will always have an (x, y) of (0, 0) and retain it's size.</p>\n\n<p><a href=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P3-UI-Layout/assets/frame_vs_bounds.png\" target=\"_blank\">\n          <img src=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P3-UI-Layout/assets/frame_vs_bounds.png\" alt=\"Frame vs Bounds\" title=\"\">\n        </a></p>\n</div><p>With our new knowledge, let's properly re-position and re-size our header view.</p><h2>Setting The Header View Rect</h2><p>Looking back at our design, we can determine the <code>CGRect</code> of our header view.</p><div class=\"challenge\">\n<p>\nWhat should the <code>CGRect</code> (x, y, width, height) of our header view be?</p>\n\n<p><a href=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P3-UI-Layout/assets/nav_bar_dimensions.png\" target=\"_blank\">\n          <img src=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P3-UI-Layout/assets/nav_bar_dimensions.png\" alt=\"Header View Dimensions\" title=\"\">\n        </a></p>\n</div><!-- break --><div class=\"solution\">\n<p>\nThe <em>frame</em> of our header view is (0, 0, 375, 105).</p>\n</div><p>Let's change our current header view's frame in storyboard.</p><div class=\"action\">\n<p>\nIn <code>Main.storyboard</code> perform the following:</p>\n\n<ol>\n<li>Select the header view (UIView) in <em>Interface Builder</em>\n</li>\n<li>With the header view selected, open the <em>Size Inspector</em> in the <em>Utilities area</em>.</li>\n<li>Find the view's <code>Frame Rectangle</code> fields. Change the X, Y, Width and Height values in the size inspector to the value of the rect in the solution above.</li>\n</ol>\n\n<p><a href=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P3-UI-Layout/assets/fix_nav_bar_rect.png\" target=\"_blank\">\n          <img src=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P3-UI-Layout/assets/fix_nav_bar_rect.png\" alt=\"Fixed Header View\" title=\"\">\n        </a></p>\n\n<p>Let's see if our changes worked! Build and run the app in the iPhone 8 simulator by clicking the run button in the toolbar.</p>\n</div><p>You should see the custom header view against your off-white root view in the simulator. Nothing fancy yet!</p><p><a href=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P3-UI-Layout/assets/fixed_nav_bar_simulator.png\" target=\"_blank\">\n          <img src=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P3-UI-Layout/assets/fixed_nav_bar_simulator.png\" alt=\"Fixed Header Simulator\" title=\"\">\n        </a></p><p>But what happens if we run our app in a simulator with a different size screen?</p>"},{"id":"T0E6OlNlY3Rpb24tMTA4","title":"Handling Different Screen Sizes","htmlContent":"<p>Let's revisit our previous diagram explaining a view's frame within the iOS coordinate system.</p><p><a href=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P3-UI-Layout/assets/nav_bar_dimensions.png\" target=\"_blank\">\n          <img src=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P3-UI-Layout/assets/nav_bar_dimensions.png\" alt=\"Header View Dimensions\" title=\"\">\n        </a></p><p>What would happen if our app was ran across multiple different screen sizes?</p><p><a href=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P3-UI-Layout/assets/fixed_nav_bar_diff_screens.png\" target=\"_blank\">\n          <img src=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P3-UI-Layout/assets/fixed_nav_bar_diff_screens.png\" alt=\"Fixed Header View With Different Screen Sizes\" title=\"\">\n        </a></p><p>As you can see, the frame of the <code>UIView</code> needs to be different for each device with a different screen size.</p><div class=\"challenge\">\n<p>\nCan you think of some ways of how we could solve this problem?</p>\n</div><h2>Introducing Auto-Layout</h2><p>One way we could solve different frames for each screen size is by programmatically calculating and setting each view's frame. However, that would be super messy and lead to us having to write a lot of code just make sure each view is the right size for each screen.</p><p>To solve this problem, Apple created a relative positioning tool called <em>Auto-Layout</em>. With <em>Auto-Layout</em>, we define constraints.</p><p>Constraints are rules where you can define the relative positioning or size between two views. <em>Auto-Layout</em> will then calculate all the math and set our view's frame so that all of the constraints (rules) are followed. This allows us to build dynamic view layouts that re-position and re-shape for any screen size.</p><p>For example, we could give our example view the following constraints:</p><ul>\n<li>Top: 20pts from Super View (Root View) Top Edge</li>\n<li>Leading (Left): 40pts from  Super View (Root View) Leading Edge</li>\n<li>Trailing (Right): -80pts from  Super View (Root View) Trailing Edge</li>\n<li>Bottom: -380pts from bottom</li>\n</ul><div class=\"info\">\n<p>\nNote the positive and negative values that are based on the direction of the iOS coordinate system.</p>\n</div><p><a href=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P3-UI-Layout/assets/constraints_example.png\" target=\"_blank\">\n          <img src=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P3-UI-Layout/assets/constraints_example.png\" alt=\"Constraints Example\" title=\"\">\n        </a></p><p>Now if the screen changes, let's see how our view will react:</p><p><a href=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P3-UI-Layout/assets/constraints_example_diff_screens.png\" target=\"_blank\">\n          <img src=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P3-UI-Layout/assets/constraints_example_diff_screens.png\" alt=\"Constraints Example\" title=\"\">\n        </a></p><p>See how auto-layout calculates the view's frame based on our constraints for each different screen size?</p><p>If instead, we wanted give the view a fixed width or height, we can also add constraints as fixed constants. Let's give our example view a new set of constraints:</p><ul>\n<li>Top: 20pts from Super View (Root View) Top Edge</li>\n<li>Leading (Left): 40pts from  Super View (Root View) Leading Edge</li>\n<li>Width: 150pts</li>\n<li>Height: 200pts</li>\n</ul><p><a href=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P3-UI-Layout/assets/fixed_size_constraint_example.png\" target=\"_blank\">\n          <img src=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P3-UI-Layout/assets/fixed_size_constraint_example.png\" alt=\"Fixed Size Constraints Example\" title=\"\">\n        </a></p><p>Auto-layout and constraints give us an easy way to build dynamic view layouts for any iOS device.</p><h2>Determining Constraints</h2><p>Let's set our first constraints by changing our header view in <em>Interface Builder</em> to make use of constraints.</p><div class=\"challenge\">\n<p>\nWhat constraints should we set for our header view? <a href=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P3-UI-Layout/assets/nav_bar_dimensions.png\" target=\"_blank\">\n          <img src=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P3-UI-Layout/assets/nav_bar_dimensions.png\" alt=\"Header View Dimensions\" title=\"\">\n        </a></p>\n</div><!-- break --><div class=\"solution\">\n<p>\nOur header view would have the following constraints:</p>\n\n<ul>\n<li>Top: 0 from Super View (Root View) Top Edge</li>\n<li>Leading (Left): 0 from Super View (Root View) Leading Edge</li>\n<li>Trailing (Right): 0 from Super View (Root View) Trailing Edge</li>\n<li>Height: 105 fixed constant</li>\n</ul>\n</div><p>Looks pretty good. Let's look at our header view with these constraints across each device:</p><p><a href=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P3-UI-Layout/assets/nav_bar_w_fixed_height_constraint.png\" target=\"_blank\">\n          <img src=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P3-UI-Layout/assets/nav_bar_w_fixed_height_constraint.png\" alt=\"Header View With Fixed Height Constraint\" title=\"\">\n        </a></p><p>Hold on. Not so fast. With the introduction of the iPhone X, the sensor housing (the top notch) requires to add some additional thought to our header view frame.</p><p><a href=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P3-UI-Layout/assets/nav_bar_fixed_height_problem.png\" target=\"_blank\">\n          <img src=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P3-UI-Layout/assets/nav_bar_fixed_height_problem.png\" alt=\"Header View Fixed Height Problem\" title=\"\">\n        </a></p><p>Because the top notch, we'll need to make calculate the header view's height based on the bottom of the top notch for the iPhone X.</p><p>To help us handle this, Apple has provided us with the <em>Safe Area</em>.</p><h2>Safe Area</h2><p>The <em>Safe Area</em> provides us with valuable layout information to help us properly create constraints for our views. In our case, the top <em>Safe Area</em> provides us with the bottom of the <em>Status Bar</em> for each device:</p><p><a href=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P3-UI-Layout/assets/safe_area.png\" target=\"_blank\">\n          <img src=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P3-UI-Layout/assets/safe_area.png\" alt=\"Safe Area\" title=\"\">\n        </a></p><p>Revise our original constraints, we'll need to replace our height constraint with a bottom constraint that is -85 from the top <em>Safe Area</em>. Now our header view dynamically calculate it's layout correctly across each device.</p><p><a href=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P3-UI-Layout/assets/nav_bar_correct_height.png\" target=\"_blank\">\n          <img src=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P3-UI-Layout/assets/nav_bar_correct_height.png\" alt=\"Header View Correct Height\" title=\"\">\n        </a></p><p>It might be a little hard to see, but the height of the header view is slightly bigger for the iPhone X because of it's top notch.</p><p>With our correct constraints, let's set them in <em>Interface Builder</em>.</p><h2>Setting Our First Constraints</h2><p>Let's set our constraints in <em>Interface Builder</em>. First we'll start by adding our top, leading (left) and trailing (right) constraints.</p><div class=\"action\">\n<p>\nOpen <code>Main.storyboard</code> from your <em>Project Navigator</em>. Select your header view (<code>UIView</code>) and add the following constraints:</p>\n\n<p><video width=\"100%\" controls><source src=\"https://s3.amazonaws.com/mgwu-misc/Tip+Calculator+Swift+4/p3_ui_layout/edge_constraints_nav_bar.mp4\" type=\"video/mp4\"></source></video></p>\n\n<p>With our header view selected, we click on the <em>Add New Constraints</em> button and set each of the edge constraints:</p>\n\n<ul>\n<li>\n<em>Top Edge</em> of header view 0pts to <em>Top Edge</em> of root view</li>\n<li>\n<em>Leading (Left) Edge</em> of header view 0pts to <em>Leading (Left) Edge</em> of root view</li>\n<li>\n<em>Trailing (Right) Edge</em> of header view 0pts to <em>Trailing (Right) Edge</em> of root view</li>\n</ul>\n</div><p>Currently, our header view has a incomplete set of constraints. We haven't added a constraint to define the view's height yet. If we run the app now, we won't see our header view because it's height will be 0. Xcode and <em>Interface Builder</em> try to warn us of this:</p><p><a href=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P3-UI-Layout/assets/constraint_errors.png\" target=\"_blank\">\n          <img src=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P3-UI-Layout/assets/constraint_errors.png\" alt=\"Constraint Errors\" title=\"\">\n        </a></p><p>You'll notice above:</p><ol>\n<li>a red error arrow that lists missing constraints in your document outline</li>\n<li>red highlights around the custom header view in your storyboard</li>\n<li>a warning in the Xcode project status bar</li>\n</ol><p>Let's add the final constraint to define the header view's height.</p><div class=\"action\">\n<p>\nAdd a constraint from the bottom edge of the header view to the top edge of the <em>Safe Area</em>: <video width=\"100%\" controls><source src=\"https://s3.amazonaws.com/mgwu-misc/Tip+Calculator+Swift+4/p3_ui_layout/nav_bar_safe_area_constraint.mp4\" type=\"video/mp4\"></source></video></p>\n\n<p>To add the constraint in the video, follow the steps below:</p>\n\n<ol>\n<li>Select the header view (<code>UIView</code>) in the <em>Document Outline</em>.</li>\n<li>With the header view selected, hold down the control button (ctrl) and click-drag from the header view to the <em>Safe Area</em> view in your <em>Document Outline</em>.</li>\n<li>Once you let go, you'll see a pop-up with the options to add a new constraint. Select <em>Vertical Spacing</em>. This will set a vertical spacing constraint from the top edge of our header view to the top edge of the <em>Safe Area</em>.</li>\n<li>(Optional) If you'd like to adjust the constraint, you can click on it and adjust it's values in the <em>Size Inspector</em>.</li>\n</ol>\n</div><p>Congrats, we've added our first set of constraints to our header view. Try running your app in multiple different simulators and see if our header view properly adjusts it's frame to each device.</p><p><a href=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P3-UI-Layout/assets/dynamic_nav_bar_diff_devices.png\" target=\"_blank\">\n          <img src=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P3-UI-Layout/assets/dynamic_nav_bar_diff_devices.png\" alt=\"Auto-Layout Header View Multiple Devices\" title=\"\">\n        </a></p><p>It works! Next, we'll dive deeper into <em>auto-layout</em> and the different kind of constraints that are available to use.</p>"},{"id":"T0E6OlNlY3Rpb24tMTA5","title":"Different Types of Constraints","htmlContent":"<p>To properly setup constraints for our header view, we've only used one type of constraints but there are many different types of constraints that you can use to build complex UI layouts. Before setting up constraints for any of our other fews, let's look at common constraints we can use to build dynamic layouts with <em>auto-layout</em>.</p><h2>Relative Positioning</h2><p>First, let's review our relative positioning constraint. Relative positioning allows to position a view relative to another view. For example, we can create a constraint that positions the blue view 45pts from the trailing (right) side of the red view:</p><p><a href=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P3-UI-Layout/assets/relative_positioning_positive.png\" target=\"_blank\">\n          <img src=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P3-UI-Layout/assets/relative_positioning_positive.png\" alt=\"Relative Positioning Positive\" title=\"\">\n        </a></p><p>Positive and negative values (relative to the iOS coordinate system) denote the direction of the constraint. For example, we can instead add a constraint that positions the blue view -75pts from the trailing (right) side of the red view:</p><p><a href=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P3-UI-Layout/assets/relative_positioning_negative.png\" target=\"_blank\">\n          <img src=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P3-UI-Layout/assets/relative_positioning_negative.png\" alt=\"Relative Positioning Negative\" title=\"\">\n        </a></p><div class=\"info\">\n<p>\nWhen you're creating relative positioning constraints, you'll need to keep in mind which view's edge the constraint is starting from, the other view's edge where the constraint is ending at and the position or negative value (direction) of the constraint.</p>\n</div><p>When you're setting your relative positioning constraints, make sure you're aware of what they're relative to. For example, let's set the blue view 20pts below the red view:</p><p><a href=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P3-UI-Layout/assets/relative_positioning_top_edge.png\" target=\"_blank\">\n          <img src=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P3-UI-Layout/assets/relative_positioning_top_edge.png\" alt=\"Relative Positioning Top Edge\" title=\"\">\n        </a></p><p>But is that what we wanted? In the case above, we set our blue view to have a constraint of 20pts below the red view but relative to the wrong edge of the red view!</p><p>This is probably what we really intended:</p><p><a href=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P3-UI-Layout/assets/relative_positioning_bottom_edge.png\" target=\"_blank\">\n          <img src=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P3-UI-Layout/assets/relative_positioning_bottom_edge.png\" alt=\"Relative Positioning Bottom Edge\" title=\"\">\n        </a></p><p>As you can see, it's a very common mistake to accidentally set constraints relative to the wrong edge or sometimes even the wrong view!</p><div class=\"info\">\n<p>\nIt's also important to take the <em>Safe Area</em> into consideration when setting a view relative to the root view. If you're setting the top edge of your view to the top edge of the root view, you'll need to verify that you don't accidentally set it to the top edge of the <em>Safe Area</em> instead, or vice versa.</p>\n</div><h2>Constant Size (Height or Width)</h2><p>As we briefly discussed earlier, it's also possible to set fixed constant constraints. These are used to set a fixed width or height of a view. For example, we can give a view a fixed width and height of 100pts:</p><p><a href=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P3-UI-Layout/assets/fixed_size_constraints.png\" target=\"_blank\">\n          <img src=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P3-UI-Layout/assets/fixed_size_constraints.png\" alt=\"Fixed Size Constraints\" title=\"\">\n        </a></p><p>In this case, the red view will always remain the same size (100x100) regardless of changing screen sizes.</p><div class=\"info\">\n<p>\nIf you run into a situation where you've added your constraints but don't see your view, you might have forgotten to add certain constraints. Remember, each view's frame must be able to be determined by it's auto-layout constraints.</p>\n\n<p>In the previous example, if we forgot to add the height constraint, our view wouldn't show up because the height of it's frame is 0.</p>\n</div><h2>Center (With Offset) In Superview</h2><p>Another positioning constraint we can use is aligning center axes vertically or horizontally. For example, we can create a constraint that vertically aligns the blue view's center to red views:</p><p><a href=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P3-UI-Layout/assets/centers_vertically_aligned.png\" target=\"_blank\">\n          <img src=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P3-UI-Layout/assets/centers_vertically_aligned.png\" alt=\"Centers Vertically Aligned\" title=\"\">\n        </a></p><p>Or we horizontally align the two views:</p><p><a href=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P3-UI-Layout/assets/centers_horizontally_aligned.png\" target=\"_blank\">\n          <img src=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P3-UI-Layout/assets/centers_horizontally_aligned.png\" alt=\"Centers Horizontally Aligned\" title=\"\">\n        </a></p><p>You can also choose to offset (positive or negative to determine direction) from the superview:</p><p><a href=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P3-UI-Layout/assets/centers_vertically_aligned_offset.png\" target=\"_blank\">\n          <img src=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P3-UI-Layout/assets/centers_vertically_aligned_offset.png\" alt=\"Centers Vertically Aligned Offset\" title=\"\">\n        </a></p><h2>Aspect Ratio</h2><p>Aspect ratio constraints are also available. You can set the height to be a ratio of the width or vice versa. This can be useful if you want to make sure the view is always a square (1:1 aspect ratio) or if you decide that the height will always be 1/2 of the width (1:2 aspect ratio).</p><p>In the following example, we set the aspect ratio to (1:3) where the height is a third of the width:</p><p><a href=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P3-UI-Layout/assets/aspect_ratio.png\" target=\"_blank\">\n          <img src=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P3-UI-Layout/assets/aspect_ratio.png\" alt=\"Aspect Ratio\" title=\"\">\n        </a></p><h2>Equal (Ratio) To Other Constraint</h2><p>The last constraint that we'll cover is the ability to set constraints relative to the ratio of another constraint. This is useful when we want certain views to size themselves relative to other views. For example, we can set the height of the blue view to be (1:2), or half, of the red view:</p><p><a href=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P3-UI-Layout/assets/relative_ratio.png\" target=\"_blank\">\n          <img src=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P3-UI-Layout/assets/relative_ratio.png\" alt=\"Relative Rati0\" title=\"\">\n        </a></p><p>In our tip calculator, we'll use this constraint to size the input and output cards to be of equal heights.</p>"},{"id":"T0E6OlNlY3Rpb24tMTEw","title":"Setting Auto-Layout For Our View Grouping","htmlContent":"<p>Let's take an other look at our design:</p><p><a href=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P3-UI-Layout/assets/tc_design_reference.png\" target=\"_blank\">\n          <img src=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P3-UI-Layout/assets/tc_design_reference.png\" alt=\"TC Design\" title=\"\">\n        </a></p><p>Next, we're going to setup the main views (and their constraints) for each UI group. In other words, we'll add the objects and constraints below:</p><p><a href=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P3-UI-Layout/assets/ui_groups_with_dimensions.png\" target=\"_blank\">\n          <img src=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P3-UI-Layout/assets/ui_groups_with_dimensions.png\" alt=\"UI Groups With Dimensions\" title=\"\">\n        </a></p><h2>Implementing Our Constraints</h2><p>We've already finished implementing the foundation for our header view. We'll repeat a similar process for each of our remaining UI groups.</p><p>With our header complete, let's move on to implementing the tip input card.</p><h3>Input Card View</h3><div class=\"action\">\n<p>\nOpen <code>Main.storyboard</code>. Add a new <code>UIView</code> and set the following constraints:</p>\n\n<p><video width=\"100%\" controls><source src=\"https://s3.amazonaws.com/mgwu-misc/Tip+Calculator+Swift+4/p3_ui_layout/add_input_card_w_constraints.mp4\" type=\"video/mp4\"></source></video></p>\n\n<p>Step by step:</p>\n\n<ol>\n<li>Drag a <code>UIView</code> from the <em>Object Library</em> onto the root view.</li>\n<li>Click the <code>Add New Constraints</code> button at the bottom right corner of the <em>Interface Builder Editor</em> window.</li>\n<li>Set the following constraints:\n\n<ul>\n<li>(Input Card) <em>Top Edge</em> 24pts from Header View <em>Bottom Edge</em>\n</li>\n<li>(Input Card) <em>Leading (Left) Edge</em> 15pts from Super View (Root View) <em>Leading (Left) Edge</em>\n</li>\n<li>(Input Card) <em>Trailing (Right) Edge</em> 15pts from Super View <em>Trailing (Right) Edge</em>\n</li>\n</ul>\n</li>\n</ol>\n</div><p>At this point, you'll see an <em>auto-layout</em> error because your new (input card) view is missing a height constraint. Ignore this warning for now, we'll fix this soon.</p><p>Next, we'll add our output card and it's constraints.</p><h3>Output Card View</h3><div class=\"action\">\n<p>\nIn storyboard, add a new <code>UIView</code> and set the following constraints:</p>\n\n<p><video width=\"100%\" controls><source src=\"https://s3.amazonaws.com/mgwu-misc/Tip+Calculator+Swift+4/p3_ui_layout/add_output_card_w_constraints.mp4\" type=\"video/mp4\"></source></video></p>\n\n<p>Step by step:</p>\n\n<ol>\n<li>Drag a <code>UIView</code> from the <em>Object Library</em> onto the view controller's root view, below the input card.</li>\n<li>Click the <code>Add New Constraints</code> button at the bottom right corner of the <em>Interface Builder Editor</em> window.</li>\n<li>Set the following constraints:\n\n<ul>\n<li>(Output Card) <em>Top Edge</em> 24pts from Input Card <em>Bottom Edge</em>\n</li>\n<li>(Output Card) <em>Leading Edge</em> 15pts from Super View <em>Leading Edge</em>\n</li>\n<li>(Output Card) <em>Trailing Edge</em> 15pts from Super View <em>Trailing Edge</em>\n</li>\n</ul>\n</li>\n</ol>\n</div><p>We'll also add an equal height constraints between both input and output card views.</p><div class=\"action\">\n<p>\nAdd an equal heights constraint between both input and output cards:</p>\n\n<p><video width=\"100%\" controls><source src=\"https://s3.amazonaws.com/mgwu-misc/Tip+Calculator+Swift+4/p3_ui_layout/add_cards_equal_height_constraint.mp4\" type=\"video/mp4\"></source></video></p>\n\n<p>Step by step:</p>\n\n<ol>\n<li>Select the output card view.</li>\n<li>With the output card selected, hold down shift and then click on the input card view. This will allow you to select both card views.</li>\n<li>Click the <code>Add New Constraints</code> button at the bottom right corner of the <em>Interface Builder Editor</em> window.</li>\n<li>In the popup prompt, select <code>Equal Heights</code> and add the selected constraint.</li>\n</ol>\n</div><p>Xcode should still show an <em>auto-layout</em> error because we haven't added enough constraints for it determine the height of each card view. Ignore this warning for now, this will be fixed once we add our reset button.</p><h3>Reset Button</h3><div class=\"action\">\n<p>\nIn storyboard, add a new <code>UIButton</code> and set the following constraints:</p>\n\n<p><video width=\"100%\" controls><source src=\"https://s3.amazonaws.com/mgwu-misc/Tip+Calculator+Swift+4/p3_ui_layout/add_reset_button_w_constraints.mp4\" type=\"video/mp4\"></source></video></p>\n\n<p>Step-by-step:</p>\n\n<ol>\n<li>Drag a <code>UIButton</code> from the <em>Object Library</em> onto the view controller's root view, below the output card.</li>\n<li>Click the <code>Add New Constraints</code> button at the bottom right corner of the <em>Interface Builder Editor</em> window.</li>\n<li>Set the following constraints:\n\n<ul>\n<li>(Reset Button) <em>Top Edge</em> 24pts from Output Card <em>Bottom Edge</em>\n</li>\n<li>(Reset Button) <em>Leading Edge</em> 15pts from Super View <em>Leading Edge</em>\n</li>\n<li>(Reset Button) <em>Trailing Edge</em> 15pts from Super View <em>Trailing Edge</em>\n</li>\n<li>(Reset Button) <em>Bottom Edge</em> 24pts from Super View <em>Bottom Edge</em>\n</li>\n<li>(Reset Button) <em>Height</em> of 60pts</li>\n</ul>\n</li>\n</ol>\n</div><p>By default, our button has a clear background color. To make our reset button easier to see, let's change it's background color from <code>Clear</code> to <code>tcDarkBlue</code>.</p><div class=\"action\">\n<p>\nChange the <em>Background color</em> of the reset button:</p>\n\n<p><video width=\"100%\" controls><source src=\"https://s3.amazonaws.com/mgwu-misc/Tip+Calculator+Swift+4/p3_ui_layout/set_reset_button_bg_color.mp4\" type=\"video/mp4\"></source></video></p>\n\n<p>Step-by-step:</p>\n\n<ol>\n<li>Select the <em>Reset Button</em>.</li>\n<li>With the <em>Reset Button</em> selected, navigate to the <em>Attributes Inspector</em> in the <em>Utilities area</em>.</li>\n<li>Scroll down until you find the <code>Background</code> field. This field allows you to set the button's background color.</li>\n<li>Locate the blue dropdown button and set the button's background color from <code>Clear</code> to <code>tcDarkBlue</code>.</li>\n</ol>\n</div><!-- break --><div class=\"info\">\n<p>\nOur <em>auto-layout</em> warning is gone! After adding our reset button and it's constraints, <em>auto-layout</em> can calculate the height of each input/output card using the equal heights constraint.</p>\n</div><p>We've finished implementing the main view for each of our respective UI groups. For each group, we added the appropriate <code>UIView</code> object and set it's corresponding constraints.</p><p>Before moving on, let's test that everything looks as expected.</p>"},{"id":"T0E6OlNlY3Rpb24tMTEx","title":"Testing Our Constraints","htmlContent":"<p>To catch bugs or missteps early, it's always good to build and run your code often. Let's go ahead and do that now to test that our constraints are working correctly.</p><div class=\"action\">\n<p>\nIn the toolbar, click the <em>Run</em> button.</p>\n</div><p>If everything goes as expected, you should see the following in your simulator:</p><p><a href=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P3-UI-Layout/assets/finished_ui_groups.png\" target=\"_blank\">\n          <img src=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P3-UI-Layout/assets/finished_ui_groups.png\" alt=\"Finished UI Groups\" title=\"\">\n        </a></p><p>Try running our project on different simulators. You'll notice that our view dynamically adjust and re-size for any screen size:</p><p><a href=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P3-UI-Layout/assets/finished_ui_groups_diff_devices.png\" target=\"_blank\">\n          <img src=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P3-UI-Layout/assets/finished_ui_groups_diff_devices.png\" alt=\"Finished UI Groups Different Devices\" title=\"\">\n        </a></p><h2>Conclusion</h2><p>In this section, we learned about how to layout our UI; first with frames and later with <em>auto-layout</em>. We learned about constraints and their importance in building dynamic view layouts for multiple devices. And finally, we put our knowledge into practice by implementing a scaffolding for our tip calculator design.</p><p>In the next section, we'll build off of our UI by fully implementing and styling each of our UI groups.</p>"}]},"next":{"id":"T0E6OlBhZ2UtMzk=","slug":"implementing-subviews","title":"Implementing Subviews"},"previous":{"id":"T0E6OlBhZ2UtMzk=","slug":"implementing-subviews","title":"Implementing Subviews"}},{"id":"T0E6OlBhZ2UtMzk=","title":"Implementing Subviews","slug":"implementing-subviews","sections":{"nodes":[{"id":"T0E6OlNlY3Rpb24tMTEy","title":"Implementing Subviews","htmlContent":"<p>In the previous section, we implemented a skeleton of each of the UI groups in storyboard. If you build and run your project, your app should look like the following:</p><p><a href=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P4-Implementing-Subviews/assets/finished_ui_groups.png\" target=\"_blank\">\n          <img src=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P4-Implementing-Subviews/assets/finished_ui_groups.png\" alt=\"Finished UI Skeleton\" title=\"\">\n        </a></p><p>In this section, we'll finish building each of our <em>view groups</em>:</p><ol>\n<li>Header</li>\n<li>Tip Input Card</li>\n<li>Tip Output Card</li>\n<li>Reset Button</li>\n</ol><p>To finish implementing each of our <em>view groups</em>, we'll need to the process below:</p><ol>\n<li>Add each of the correct <code>UIKit</code> objects</li>\n<li>Identify and set <em>auto-layout</em> constraints for each subview</li>\n<li>Configure each subview's attributes to match the designs</li>\n<li>Create the appropriate <code>IBOutlets</code> and <code>IBActions</code>\n</li>\n</ol><p>Let's start by finishing the first UI group: our header.</p>"},{"id":"T0E6OlNlY3Rpb24tMTEz","title":"Header View","htmlContent":"<p>In our previous step, we've already added a base view (<code>UIView</code>) for our header. In it's current state, our header view looks like the following:</p><p><a href=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P4-Implementing-Subviews/assets/current_nav_bar.png\" target=\"_blank\">\n          <img src=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P4-Implementing-Subviews/assets/current_nav_bar.png\" alt=\"Current Header View\" title=\"\">\n        </a></p><p>To finish implementing our header view, we'll need to identify and add the remaining subviews.</p><div class=\"challenge\">\n<p>\nUsing the design below, can you identify the views we'll need to finish building the UI for our header view?</p>\n\n<p><a href=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P4-Implementing-Subviews/assets/nav_bar_design.png\" target=\"_blank\">\n          <img src=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P4-Implementing-Subviews/assets/nav_bar_design.png\" alt=\"Header View Design\" title=\"\">\n        </a></p>\n</div><!-- break --><div class=\"solution\">\n<p>\nWe'll need the following view objects to build our header:</p>\n\n<ul>\n<li>\n<code>UILabel</code>: title label</li>\n<li>\n<code>UISwitch</code>: theme color switch</li>\n</ul>\n</div><p>After identifying both of the view objects we'll need to add, we'll need to add them and set each of their respective constraints. Let's start with the title label!</p><h2>Title Label</h2><h3>Identifying Constraints</h3><p>Before we starting adding constraints in storyboard, let's take a step back and think of all the constraints we'll need for our title label.</p><div class=\"challenge\">\n<p>\nUsing the design below, identify each of the <em>auto-layout</em> constraints for your title label. Write each of the constraints down on a sheet of paper.</p>\n\n<p>Hint: the red area represents the frame of the label.</p>\n\n<p><a href=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P4-Implementing-Subviews/assets/nav_bar_label_dimensions.png\" target=\"_blank\">\n          <img src=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P4-Implementing-Subviews/assets/nav_bar_label_dimensions.png\" alt=\"Header View Label Dimensions\" title=\"\">\n        </a></p>\n</div><p>Check your answer with the solution below.</p><div class=\"solution\">\n<p>\nBased on our design, our label will need the following constraints:</p>\n\n<p><a href=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P4-Implementing-Subviews/assets/nav_bar_label_constraints.png\" target=\"_blank\">\n          <img src=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P4-Implementing-Subviews/assets/nav_bar_label_constraints.png\" alt=\"Header View Label Constraints\" title=\"\">\n        </a></p>\n\n<p><strong>Constraints</strong>:</p>\n\n<ul>\n<li>(Label) Leading Edge 24pts from Super View (Header View) Leading Edge</li>\n<li>(Label) Bottom Edge 0pts from Super View Bottom Edge</li>\n<li>(Label) Top Edge 0pts from Safe Area Top Edge</li>\n</ul>\n</div><h3>Adding Constraints</h3><p>After identifying our constraints, we can use <em>Interface Builder</em> to add our new <code>UILabel</code> and it's constraints.</p><div class=\"action\">\n<p>\nOpen <code>Main.storyboard</code> and implement your title label and it's constraints:</p>\n\n<p><video width=\"100%\" controls><source src=\"https://s3.amazonaws.com/mgwu-misc/Tip+Calculator+Swift+4/p4_implementing_subviews/add_nav_bar_label_w_constraints.mp4\" type=\"video/mp4\"></source></video></p>\n\n<p>Step-by-step:</p>\n\n<ol>\n<li>Drag a <code>UILabel</code> from the <em>Object Library</em> and drop it on top of your header view (<code>UIView</code>).</li>\n<li>With your new <code>UILabel</code> selected, click the <code>Add New Constraints</code> button.</li>\n<li>Add the following first two constraints using the <code>Add New Constraints</code> popup:\n\n<ul>\n<li>(Label) Leading Edge 24pts from Super View Leading Edge</li>\n<li>(Label) Bottom Edge 0pts from Super View Bottom Edge</li>\n</ul>\n</li>\n<li>To add the final constraint, select your <code>UILabel</code> in the <em>Document Outline</em>.</li>\n<li>With your <code>UILabel</code> selected, hold control (ctrl) and click-drag to the <em>Safe Area</em> object in the <em>Document Outline</em>.</li>\n<li>You should see a popup to add a new constraint. Select <code>Vertical Spacing</code>. Wait a second, our new <code>Vertical Spacing</code> constraint isn't not properly configured.</li>\n<li>Hover over the new <code>Vertical Spacing</code> and click on it. You should see it's attributes appear in the <em>Attributes Inspector</em>.</li>\n<li>In the <em>Attributes Inspector</em>, change the constraint's attributes:\n\n<ul>\n<li>\n<em>Second Item</em>: Change from <code>Label.Bottom</code> to <code>Top</code>\n</li>\n<li>\n<em>Constant</em>: Change from <code>-85</code> to <code>0</code>\n</li>\n</ul>\n</li>\n</ol>\n</div><!-- break --><div class=\"info\">\n<p>\nIdentifying and setting the <em>auto-layout</em> constraints for each view object can be tricky for newbies. If you find yourself struggling, slow down and try to break down your layout problem into smaller chunks. As you continue to practice, working with constraints will become easier and easier.</p>\n</div><p>Nice! We've added a title label to our header. If you build and run your project, you'll see the following:</p><p><a href=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P4-Implementing-Subviews/assets/nav_bar_label_no_styling.png\" target=\"_blank\">\n          <img src=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P4-Implementing-Subviews/assets/nav_bar_label_no_styling.png\" alt=\"Header Title Label Without Styling\" title=\"\">\n        </a></p><p>But... it's still off. Our title label still doesn't look like our final design.</p><p>That's because we'll need to use the <em>Attribute Inspector</em> to set the <code>UILabel</code> attributes to match our designs.</p><h3>Configuring Attributes</h3><div class=\"action\">\n<p>\nIn <code>Main.storyboard</code>, select your header view's title label. Navigate to the <em>Attributes Inspector</em> in the <em>Utilities area</em> and change the following attributes:</p>\n\n<ul>\n<li>\n<em>Text</em>: Change from <code>Label</code> to <code>Tip Calculator</code> <a href=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P4-Implementing-Subviews/assets/set_nav_bar_label_text.png\" target=\"_blank\">\n          <img src=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P4-Implementing-Subviews/assets/set_nav_bar_label_text.png\" alt=\"Set Header View Label Text\" title=\"\">\n        </a>\n</li>\n<li>\n<em>Font</em>: Change from <code>System 17.0</code> to <code>System Bold 24.0</code> <a href=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P4-Implementing-Subviews/assets/set_nav_bar_label_font.png\" target=\"_blank\">\n          <img src=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P4-Implementing-Subviews/assets/set_nav_bar_label_font.png\" alt=\"Set Header View Label Font\" title=\"\">\n        </a>\n</li>\n<li>\n<em>Font Color</em>: Use the blue dropdown to change from <code>Default</code> to <code>tcCharcoal</code> <a href=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P4-Implementing-Subviews/assets/set_nav_bar_label_text_color.png\" target=\"_blank\">\n          <img src=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P4-Implementing-Subviews/assets/set_nav_bar_label_text_color.png\" alt=\"Set Header View Text Color\" title=\"\">\n        </a>\n</li>\n</ul>\n</div><p>After configuring each of the attributes above, your title label should look like the following:</p><p><a href=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P4-Implementing-Subviews/assets/nav_bar_label_w_styling.png\" target=\"_blank\">\n          <img src=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P4-Implementing-Subviews/assets/nav_bar_label_w_styling.png\" alt=\"Header View Label Styled\" title=\"\">\n        </a></p><p>Looks pretty good huh? Let's move on to our <code>UISwitch</code>.</p><h2>Light/Dark Mode (Theme) Switch</h2><p>Identify constraints. Add object and set constraints. Configure attributes. Rinse. Repeat.</p><p>We'll going to repeat this process many times before this tutorial is over. Get used to this, as it's the same process you'll need to use if when you're building your own apps.</p><p>Let's start by identifying the constraints needed for our <code>UISwitch</code>.</p><h3>Identifying Constraints</h3><div class=\"challenge\">\n<p>\nUsing the design below, identify each of the <em>auto-layout</em> constraints for your theme switch. Write each of the constraints down on a sheet of paper.</p>\n\n<p>Hint: the red area represents the frame of the switch.</p>\n\n<p><a href=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P4-Implementing-Subviews/assets/nav_bar_switch_dimensions.png\" target=\"_blank\">\n          <img src=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P4-Implementing-Subviews/assets/nav_bar_switch_dimensions.png\" alt=\"Header View Switch Dimensions\" title=\"\">\n        </a></p>\n</div><p>Check your answer with the solution below.</p><div class=\"solution\">\n<p>\nBased on our design, our <code>UISwitch</code> will need the following constraints:</p>\n\n<p><a href=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P4-Implementing-Subviews/assets/nav_bar_switch_constraints.png\" target=\"_blank\">\n          <img src=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P4-Implementing-Subviews/assets/nav_bar_switch_constraints.png\" alt=\"Header View Switch With Constraints\" title=\"\">\n        </a></p>\n\n<p><strong>Constraints</strong>:</p>\n\n<ul>\n<li>(Switch) Trailing Edge 24pts from Super View (Header View) Trailing Edge</li>\n<li>(Switch) Leading Edge &ge;20pts from Label Trailing Edge</li>\n<li>(Switch) Center vertically aligned with Label Center</li>\n</ul>\n</div><h3>Adding Constraints</h3><p>Let's go ahead and add these constraints to our <code>UISwitch</code>.</p><div class=\"action\">\n<p>\nOpen <code>Main.storyboard</code> and implement your <code>UISwitch</code> and it's constraints:</p>\n\n<p><video width=\"100%\" controls><source src=\"https://s3.amazonaws.com/mgwu-misc/Tip+Calculator+Swift+4/p4_implementing_subviews/add_switch_w_constraints.mp4\" type=\"video/mp4\"></source></video></p>\n\n<p>Step-by-step:</p>\n\n<ol>\n<li>Drag a <code>UISwitch</code> from the <em>Object Library</em> and drop it next to your header title label.</li>\n<li>With your  <code>UISwitch</code> selected, click the <code>Add New Constraints</code> button.</li>\n<li>Add the following two constraints using the <code>Add New Constraints</code> popup:\n\n<ul>\n<li>(Switch) Trailing Edge 24pts from Super View Trailing Edge</li>\n<li>(Switch) Leading Edge 20pts from Label Trailing Edge</li>\n</ul>\n</li>\n<li>Hover over the switch's leading edge constraint to the label and click on it. You should see it's attributes appear in the <em>Attributes Inspector</em>.</li>\n<li>Using the <em>Attributes Inspector</em>, change the constraint's <em>Relation</em> attribute from <code>Equal</code> to <code>Greater Than or Equal</code>.</li>\n<li>Click on the <code>UISwitch</code> to select it again. Make sure you're not selecting the constraint from the previous step.</li>\n<li>With your switch selected, hold control (ctrl) and click-drag from the <code>UISwitch</code> to the <code>UILabel</code>.</li>\n<li>You should see a popup to add a new constraint. Select <code>Center Vertically</code> to vertically align your switch's center to the label's center.</li>\n</ol>\n</div><p>Nice! We've added and set our constraints for our <code>UISwitch</code>. Now, let's configure the switch's attributes.</p><h3>Configuring Attributes</h3><div class=\"action\">\n<p>\nIn <code>Main.storyboard</code>, select your header view's switch. Navigate to the <em>Attributes Inspector</em> in the <em>Utilities area</em> and change the following attributes:</p>\n\n<p><a href=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P4-Implementing-Subviews/assets/switch_attrs.png\" target=\"_blank\">\n          <img src=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P4-Implementing-Subviews/assets/switch_attrs.png\" alt=\"Switch Attributes\" title=\"\">\n        </a></p>\n\n<p><strong>Attributes:</strong></p>\n\n<ul>\n<li>\n<em>State</em>: Change from <code>On</code> to <code>Off</code>\n</li>\n<li>\n<em>On Tint</em>: Change from <code>Default</code> to <code>tcSeafoamGreen</code>\n</li>\n</ul>\n</div><p>When you're done, your custom header view should look like the following:</p><p><a href=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P4-Implementing-Subviews/assets/nav_bar_w_styling.png\" target=\"_blank\">\n          <img src=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P4-Implementing-Subviews/assets/nav_bar_w_styling.png\" alt=\"Header View With Styling\" title=\"\">\n        </a></p><h2>Adding Our IB Connections</h2><p>We're almost finished with implementing our first UI group! To finish up, we'll need to create our <code>IBOutlets</code> and <code>IBActions</code>.</p><p><code>IBOutlets</code> and <code>IBActions</code> allow our Swift code receive events and interact with our storyboard views.</p><p><code>IBOutlets</code> create an instance variable that we can reference in our Swift code. This allows us interact with our title label and switch programmatically.</p><p><code>IBActions</code> create a function that will execute code when triggered. These functions are triggered by user interaction with your UI elements. A common example is a user tapping a button. When the button is tapped, it triggers an <code>IBAction</code> that will run any code within it's corresponding function.</p><p>We'll need both of these connections later to implement our tip calculator logic.</p><p>Let's get started by creating our first <code>IBOutlet</code> for our header view (<code>UIView</code>).</p><div class=\"action\">\n<p>\nOpen your <code>Main.storyboard</code> and <code>ViewController.swift</code> files side-by-side using the <em>Assistant Editor</em>:</p>\n\n<p><video width=\"100%\" controls><source src=\"https://s3.amazonaws.com/mgwu-misc/Tip+Calculator+Swift+4/p4_implementing_subviews/using_assistant_editor.mp4\" type=\"video/mp4\"></source></video></p>\n\n<p>To create IB connections, we'll need to first open our storyboard and view controller source code side-by-side:</p>\n\n<ol>\n<li>Open your <code>Main.storyboard</code> in your main editor.</li>\n<li>Hold down the option button and click on <code>ViewController.swift</code> file in your <em>Project Navigator</em>. This will open your view controller in your <em>Assistant Editor</em>.</li>\n<li>(Optional) Use your Xcode toolbar to hide the <em>Utilities area</em> to create more space in your project.</li>\n</ol>\n</div><p>With our <code>Main.storyboard</code> and <code>ViewController.swift</code> files side-by-side, let's create an <code>IBOutlet</code> for our header.</p><div class=\"action\">\n<p>\nCreate an <code>IBOutlet</code> for your header called <code>headerView</code>:</p>\n\n<p><video width=\"100%\" controls><source src=\"https://s3.amazonaws.com/mgwu-misc/Tip+Calculator+Swift+4/p4_implementing_subviews/header_view_iboutlet.mp4\" type=\"video/mp4\"></source></video></p>\n\n<p>Step-by-step:</p>\n\n<ol>\n<li>Select your header view (<code>UIView</code>) in the <em>Document Outline</em>.</li>\n<li>With your header view selected, hold down ctrl and click-drag from the header view in your <em>Document Outline</em> to your Swift code within the <code>ViewController</code> class definition.</li>\n<li>You should see a popup for creating a new IB connection. Set the name field as <code>headerView</code>.</li>\n<li>Click <em>Connect</em> to create your new <code>IBOutlet</code>.</li>\n</ol>\n</div><p>You should see a new <code>IBOutlet</code> instance variable in your <code>ViewController</code> class:</p><pre><span class=\"kd\">class</span> <span class=\"nc\">ViewController</span><span class=\"p\">:</span> <span class=\"bp\">UIViewController</span> <span class=\"p\">{</span>\n\n    <span class=\"kr\">@IBOutlet</span> <span class=\"kr\">weak</span> <span class=\"kd\">var</span> <span class=\"nv\">headerView</span><span class=\"p\">:</span> <span class=\"bp\">UIView</span><span class=\"p\">!</span>\n\n    <span class=\"c1\">// </span><span class=\"cs\">MARK:</span><span class=\"c1\"> - View Lifecycle</span>\n\n    <span class=\"kr\">override</span> <span class=\"kd\">func</span> <span class=\"nf\">viewDidLoad</span><span class=\"p\">()</span> <span class=\"p\">{</span>\n        <span class=\"kc\">super</span><span class=\"p\">.</span><span class=\"n\">viewDidLoad</span><span class=\"p\">()</span>\n    <span class=\"p\">}</span>\n<span class=\"p\">}</span>\n</pre><p>As you can see, we can now reference our header view as <code>headerView</code> in our Swift code.</p><p>Awesome! Repetition is the mother of learning. Let's do it again.</p><div class=\"action\">\n<p>\nCreate an <code>IBOutlet</code> for your header view's title label called <code>titleLabel</code>:</p>\n\n<p><video width=\"100%\" controls><source src=\"https://s3.amazonaws.com/mgwu-misc/Tip+Calculator+Swift+4/p4_implementing_subviews/title_label_iboutlet.mp4\" type=\"video/mp4\"></source></video></p>\n\n<p>Step-by-step:</p>\n\n<ol>\n<li>Select your title label (<code>UILabel</code>) in your storyboard view controller.</li>\n<li>With your Tip Calculator label selected, hold down ctrl and click-drag from the label to your Swift code within the <code>ViewController</code> class definition.</li>\n<li>You should see a popup for creating a new IB connection. Set the name field as <code>titleLabel</code>.</li>\n<li>Click <em>Connect</em> to create your new <code>IBOutlet</code>.</li>\n</ol>\n</div><!-- break --><div class=\"info\">\n<p>\nNotice that last time we created an <code>IBOutlet</code> by ctrl-dragged from our header view in the <em>Document Outline</em>. This time we created our <code>IBOutlet</code> by ctrl-dragged directly from the label's storyboard object. Both ways of creating <code>IBOutlets</code> are valid.</p>\n</div><p>At this point, we've walked through creating an <code>IBOutlet</code> twice. It's your turn.</p><div class=\"challenge\">\n<p>\nCreate an <code>IBOutlet</code> for your <code>UISwitch</code> named <code>themeSwitch</code>. If you get stuck, go back and reference the steps we used to create the previous two <code>IBOutlets</code>.</p>\n</div><!-- break --><div class=\"solution\">\n<p>\nAfter creating an <code>IBOutlet</code> for your switch, your <code>ViewController.swift</code> file should look like the following:</p>\n<pre><span class=\"kd\">class</span> <span class=\"nc\">ViewController</span><span class=\"p\">:</span> <span class=\"bp\">UIViewController</span> <span class=\"p\">{</span>\n\n    <span class=\"kr\">@IBOutlet</span> <span class=\"kr\">weak</span> <span class=\"kd\">var</span> <span class=\"nv\">headerView</span><span class=\"p\">:</span> <span class=\"bp\">UIView</span><span class=\"p\">!</span>\n    <span class=\"kr\">@IBOutlet</span> <span class=\"kr\">weak</span> <span class=\"kd\">var</span> <span class=\"nv\">titleLabel</span><span class=\"p\">:</span> <span class=\"bp\">UILabel</span><span class=\"p\">!</span>\n    <span class=\"kr\">@IBOutlet</span> <span class=\"kr\">weak</span> <span class=\"kd\">var</span> <span class=\"nv\">themeSwitch</span><span class=\"p\">:</span> <span class=\"bp\">UISwitch</span><span class=\"p\">!</span>\n\n    <span class=\"c1\">// </span><span class=\"cs\">MARK:</span><span class=\"c1\"> - View Lifecycle</span>\n\n    <span class=\"kr\">override</span> <span class=\"kd\">func</span> <span class=\"nf\">viewDidLoad</span><span class=\"p\">()</span> <span class=\"p\">{</span>\n        <span class=\"kc\">super</span><span class=\"p\">.</span><span class=\"n\">viewDidLoad</span><span class=\"p\">()</span>\n    <span class=\"p\">}</span>\n<span class=\"p\">}</span>\n</pre>\n</div><p>After checking your solution, let's move on to creating our first <code>IBAction</code>.</p><p>We'll need to create an <code>IBAction</code> for our switch. This will allow us to execute code each time our switch is toggled from off to on and vice versa.</p><div class=\"action\">\n<p>\nOpen both your <code>Main.storyboard</code> and <code>ViewController.swift</code> file using the <em>Assistant Editor</em>. Create a new <code>IBAction</code> for your switch:</p>\n\n<p><video width=\"100%\" controls><source src=\"https://s3.amazonaws.com/mgwu-misc/Tip+Calculator+Swift+4/p4_implementing_subviews/switch_ibaction.mp4\" type=\"video/mp4\"></source></video></p>\n\n<p>Step-by-step:</p>\n\n<ol>\n<li>Select your switch (<code>UISwitch</code>) in the <em>Document Outline</em>.</li>\n<li>With your switch selected, hold down ctrl and click-drag from the switch in your <em>Document Outline</em> to your <code>ViewController</code> class.</li>\n<li>You should see a popup for creating a new IB connection. In the popup, change the <em>Connection</em> type from <code>Outlet</code> to <code>Action</code>. Changing this property allows us to create a different type of IB connection.</li>\n<li>Set the name of our action as <code>themeToggled</code>.</li>\n<li>Change the <em>Type</em> property from <code>Any</code> to <code>UISwitch</code>.</li>\n<li>Make sure the <em>Event</em> property is set as <code>Value Changed</code>. If not, use the dropdown to set it to <code>Value Changed</code>.</li>\n<li>Click <em>Connect</em> to create your new <code>IBAction</code>.</li>\n</ol>\n</div><!-- break --><div class=\"info\">\n<p>\nAfter creating your switch's <code>IBAction</code>, you can close the <em>Assistant Editor</em>. If don't have a lot of screen space, it's helpful to open and close the <em>Assistant Editor</em> as you need it.</p>\n</div><p>Let's give our new <code>IBAction</code> a test run to see that it's working correctly.</p><div class=\"action\">\n<p>\nOpen <code>ViewController.swift</code> from your <em>Project Navigator</em> and add the following code in your <code>themeToggled</code> function:</p>\n<pre><span class=\"nd\">@IBAction</span> <span class=\"n\">func</span> <span class=\"n\">themeToggled</span><span class=\"p\">(</span><span class=\"n\">_</span> <span class=\"n\">sender</span><span class=\"p\">:</span> <span class=\"n\">UISwitch</span><span class=\"p\">)</span> <span class=\"p\">{</span>\n    <span class=\"k\">if</span> <span class=\"n\">sender</span><span class=\"o\">.</span><span class=\"n\">isOn</span> <span class=\"p\">{</span>\n        <span class=\"k\">print</span><span class=\"p\">(</span><span class=\"s2\">\"switch toggled on\"</span><span class=\"p\">)</span>\n    <span class=\"p\">}</span> <span class=\"k\">else</span> <span class=\"p\">{</span>\n        <span class=\"k\">print</span><span class=\"p\">(</span><span class=\"s2\">\"switch toggled off\"</span><span class=\"p\">)</span>\n    <span class=\"p\">}</span>\n<span class=\"p\">}</span>\n</pre>\n</div><p>After adding the code above we can test our <code>IBAction</code>.</p><div class=\"action\">\n<p>\nBuild and run your project. Toggle your switch on and off a couple of times. If you look at your Xcode <em>Debugger area</em> you should see the following print statements in your console each time you toggle your switch:</p>\n\n<p><a href=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P4-Implementing-Subviews/assets/switch_console_print.png\" target=\"_blank\">\n          <img src=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P4-Implementing-Subviews/assets/switch_console_print.png\" alt=\"Switch Console Print\" title=\"\">\n        </a></p>\n</div><p>We've finished implementing the UI and IB connections for our header view. Side-by-side, your <code>Main.storyboard</code> and <code>ViewController.swift</code> files should look like the following:</p><p><a href=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P4-Implementing-Subviews/assets/finished_header_project_snapshot.png\" target=\"_blank\">\n          <img src=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P4-Implementing-Subviews/assets/finished_header_project_snapshot.png\" alt=\"Finished Header Project Snapshot\" title=\"\">\n        </a></p><p>If you build and run your project, you app should look like:</p><p><a href=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P4-Implementing-Subviews/assets/finished_header_app_snapshot.png\" target=\"_blank\">\n          <img src=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P4-Implementing-Subviews/assets/finished_header_app_snapshot.png\" alt=\"Finished Header App Snapshot\" title=\"\">\n        </a></p><p>If you're looking for more practice, good news! We'll need to repeat the same steps again for our input card, output card and reset button views. Onwards!</p><div class=\"info\">\n<p>\nAs you get more advanced, you'll learn about creating custom view objects that abstract all of it's subview components. Creating custom views makes your custom views re-usable and decouples your code. This is a little more advanced and out of the scope of this tutorial.</p>\n</div>"},{"id":"T0E6OlNlY3Rpb24tMTE0","title":"Input Card View","htmlContent":"<p>The next UI group we'll complete is our input card. Let's take another look at our design:</p><p><a href=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P4-Implementing-Subviews/assets/input_card_design.png\" target=\"_blank\">\n          <img src=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P4-Implementing-Subviews/assets/input_card_design.png\" alt=\"Input Card Design\" title=\"\">\n        </a></p><p>For our input card, we'll need to add the following UI components:</p><p><a href=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P4-Implementing-Subviews/assets/tip_input_subviews.png\" target=\"_blank\">\n          <img src=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P4-Implementing-Subviews/assets/tip_input_subviews.png\" alt=\"Tip Input Subviews\" title=\"\">\n        </a></p><p>We'll need two labels, a text field, and a segmented control. Next, let's think about how to use <em>auto-layout</em> to build our design.</p><h2>Identifying Constraints</h2><p>To build our header view, we used constraints to create our dynamic view layout. This time, we'll introduce a new tool called <code>UIStackView</code>.</p><h3>Stack Views</h3><p><code>UIStackView</code> allows us to create horizontal or vertical stacks of views. This is especially useful for easily organizing rows or columns layouts.</p><p>Let's take a look at what that looks like:</p><p><a href=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P4-Implementing-Subviews/assets/hor_and_ver_stack_views.png\" target=\"_blank\">\n          <img src=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P4-Implementing-Subviews/assets/hor_and_ver_stack_views.png\" alt=\"Horizontal and Vertical Stack Views\" title=\"\">\n        </a></p><p>In both cases, you can see that each stack view contains multiple subviews. The <code>UIStackView</code> automatically handles calculating the frame of each subview within it.</p><p>We'll use stack views to easily layout our input subviews without having to add the constraints ourselves.</p><p>Let's look at how we'll use a horizontal stack view to group our first row of views.</p><p><a href=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P4-Implementing-Subviews/assets/bill_amount_stack_view.png\" target=\"_blank\">\n          <img src=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P4-Implementing-Subviews/assets/bill_amount_stack_view.png\" alt=\"Bill Amount Stack View\" title=\"\">\n        </a></p><p>As you can see, both our <em>Bill Amount Title Label</em> and <em>Bill Amount Text Field</em> are added to a single <code>UIStackView</code>. The purple area in the image above shows the stack view's frame.</p><p>Similarly, we can use another horizontal stack view to layout our <em>Tip Percent Title</em> and <em>Tip Segmented Control</em> subviews. Let's look at what the would look like:</p><p><a href=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P4-Implementing-Subviews/assets/tip_percent_stack_view.png\" target=\"_blank\">\n          <img src=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P4-Implementing-Subviews/assets/tip_percent_stack_view.png\" alt=\"Tip Percent Stack View\" title=\"\">\n        </a></p><p>Each <code>UIStackView</code> calculates the frame of each subview within it. However, we'll still need to somehow define the frame of each <code>UIStackView</code>.</p><p>To position both of our horizontal stack views in the center of our input card, we'll use our existing knowledge of stack views and constraints.</p><p>First, we'll add a vertical stack view containing both horizontal stack views:</p><p><a href=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P4-Implementing-Subviews/assets/outer_stack_view.png\" target=\"_blank\">\n          <img src=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P4-Implementing-Subviews/assets/outer_stack_view.png\" alt=\"Outer Stack View\" title=\"\">\n        </a></p><p>Next, we'll use constraints to dynamically center the outer stack view:</p><p><a href=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P4-Implementing-Subviews/assets/outer_stack_view_constraints.png\" target=\"_blank\">\n          <img src=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P4-Implementing-Subviews/assets/outer_stack_view_constraints.png\" alt=\"Outer Stack View Constraints\" title=\"\">\n        </a></p><p>We add the following constraints to our outer stack view:</p><ul>\n<li>(Outer Stack View) Leading Edge 22pts from Super View (Input Card) Leading Edge</li>\n<li>(Outer Stack View) Trailing Edge 22pts from Super View Trailing Edge</li>\n<li>(Outer Stack View) Center vertically aligned with Super View Center</li>\n</ul><p>We'll need to add a few more width constraints to guarantee each view is of the correct width.</p><p>We'll start by adding an equal width to both inner (horizontal) stack views:</p><p><a href=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P4-Implementing-Subviews/assets/input_card_equal_widths.png\" target=\"_blank\">\n          <img src=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P4-Implementing-Subviews/assets/input_card_equal_widths.png\" alt=\"Input Card Equal Widths Constraints\" title=\"\">\n        </a></p><p>In the image above, we add the following two constraints:</p><ul>\n<li>(Inner Top Stack View) Equal Width to Outer Stack View Width</li>\n<li>(Inner Bottom Stack View) Equal Width to Outer Stack View Width</li>\n</ul><p>As the name suggests, these two <em>Equal Widths</em> constraints define the widths of the inner stack view to be the same as the outer stack view.</p><p>Last, we need to add a width constraint for our <code>UITextField</code> and <code>UISegmentedControl</code> respectively.</p><p><a href=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P4-Implementing-Subviews/assets/input_card_input_width_constraints.png\" target=\"_blank\">\n          <img src=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P4-Implementing-Subviews/assets/input_card_input_width_constraints.png\" alt=\"Input Card Input Width Constraints\" title=\"\">\n        </a></p><p>Our width constraints:</p><ul>\n<li>(Bill Amount Text Field) 118pts Width</li>\n<li>(Tip % Segmented Control) 173pts Width</li>\n</ul><p>Whew! Those are the final constraints we'll need for our input card.</p><p>As you can see, the combination of stack views and constraints give developers a lot of power to create complex UI layouts.</p><p>Now that we've figured how we're going to implement the layout for our input card, let's start building!</p><h2>Adding Constraints</h2><p>As you can see, the layout for our input card is pretty complex. To make things easier, we'll break our implementation into smaller steps.</p><p>We'll start with the inner top stack view: the <em>Bill Amount Stack View</em>.</p><h3>Bill Amount Stack View</h3><p>First, we'll need to add our stack view's sub-elements.</p><div class=\"action\">\n<p>\nIn <code>Main.storyboard</code>, add an <code>UILabel</code> and <code>UITextField</code> to your view controller:</p>\n\n<p><video width=\"100%\" controls><source src=\"https://s3.amazonaws.com/mgwu-misc/Tip+Calculator+Swift+4/p4_implementing_subviews/add_bill_amount_subviews.mp4\" type=\"video/mp4\"></source></video></p>\n\n<p>Step-by-step:</p>\n\n<ol>\n<li>Drag a <code>UILabel</code> from the <em>Object Library</em> and drop it on top of your input card view (<code>UIView</code>).</li>\n<li>Drag a <code>UITextField</code> from the <em>Object Library</em> and position it next to your previous label.</li>\n<li>Make sure both subviews are positioned horizontally side-by-side. This will be important when we create our stack view.</li>\n</ol>\n</div><p>Next, let's create our first <code>UIStackView</code> from our two new views.</p><div class=\"action\">\n<p>\nCreate the <em>Bill Amount Stack View</em> using the label and textfield:</p>\n\n<p><video width=\"100%\" controls><source src=\"https://s3.amazonaws.com/mgwu-misc/Tip+Calculator+Swift+4/p4_implementing_subviews/create_bill_amount_stack_view.mp4\" type=\"video/mp4\"></source></video></p>\n\n<ol>\n<li>Select your <em>Bill Amount Title Label</em> (<code>UILabel</code>) in your storyboard.</li>\n<li>Hold down shift and click on your <code>UITextField</code>. This allows you to select multiple items at the same time.</li>\n<li>With both label and text field selected, click on the <code>Embed In Stack</code> button near the <code>Add New Constraints</code> button. It's located in the bottom right corner of your <em>Editor area</em>.</li>\n<li>(Optional) If you look in your <em>Document Outline</em>, you can see your new <code>UIStackView</code>. If you expand your stack view in your <em>Document Outline</em> you can see each of the stack view's subviews.</li>\n</ol>\n</div><p>Your storyboard should look like the following:</p><p><a href=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P4-Implementing-Subviews/assets/bill_amount_stack_view_unstyled.png\" target=\"_blank\">\n          <img src=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P4-Implementing-Subviews/assets/bill_amount_stack_view_unstyled.png\" alt=\"Bill Amount Stack View Unstyled\" title=\"\">\n        </a></p><p>Needs some work huh? We won't worry about the styling yet. Let's move onto creating the inner bottom stack view.</p><h3>Tip Percent Stack View</h3><p>First, we'll add the <em>Tip Percent Stack View's</em> subviews.</p><div class=\"action\">\n<p>\nIn <code>Main.storyboard</code>, add an <code>UILabel</code> and <code>UISegmentedControl</code> to your view controller:</p>\n\n<p><video width=\"100%\" controls><source src=\"https://s3.amazonaws.com/mgwu-misc/Tip+Calculator+Swift+4/p4_implementing_subviews/add_tip_percent_subviews.mp4\" type=\"video/mp4\"></source></video></p>\n\n<p>Step-by-step:</p>\n\n<ol>\n<li>Drag a <code>UILabel</code> from the <em>Object Library</em> and drop it below the first label.</li>\n<li>Drag a <code>UISegmentedControl</code> from the <em>Object Library</em> and position it so that it's next to the new label and below the text field.</li>\n<li>Make sure both label and segmented control are positioned horizontally side-by-side. In addition, make sure that they're positioned below the previous stack view.</li>\n</ol>\n</div><p>Now we'll move on to create our second inner stack view.</p><div class=\"action\">\n<p>\nCreate the <em>Tip Percent Stack View</em> using the label and segmented control:</p>\n\n<p><video width=\"100%\" controls><source src=\"https://s3.amazonaws.com/mgwu-misc/Tip+Calculator+Swift+4/p4_implementing_subviews/create_tip_percent_stack_view.mp4\" type=\"video/mp4\"></source></video></p>\n\n<ol>\n<li>Select your <em>Tip Percent Title Label</em> (<code>UILabel</code>) in your storyboard.</li>\n<li>Hold down shift and click on your <code>UISegmentedControl</code>. This allows you to select multiple items at the same time.</li>\n<li>With both label and segmented control selected, click on the <code>Embed In Stack</code> button near the <code>Add New Constraints</code> button. It's located in the bottom right corner of your <em>Editor area</em>.</li>\n<li>(Optional) If you look in your <em>Document Outline</em>, you can see your new <code>UIStackView</code>. If you expand your stack view in your <em>Document Outline</em> you can see each of the stack view's subviews.</li>\n</ol>\n</div><p>Your storyboard should look like the following:</p><p><a href=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P4-Implementing-Subviews/assets/tip_percent_stack_view_unstyled.png\" target=\"_blank\">\n          <img src=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P4-Implementing-Subviews/assets/tip_percent_stack_view_unstyled.png\" alt=\"Tip Percent Stack View Unstyled\" title=\"\">\n        </a></p><p>Both stack views should still be unstyled. We'll get to that once we finish adding all our constraints.</p><p>Next, let's create our outer stack view.</p><h3>Outer Stack View</h3><div class=\"action\">\n<p>\nCreate the <em>Outer Stack View</em> using both inner (horizontal) stack views:</p>\n\n<p><video width=\"100%\" controls><source src=\"https://s3.amazonaws.com/mgwu-misc/Tip+Calculator+Swift+4/p4_implementing_subviews/create_outer_stack_view.mp4\" type=\"video/mp4\"></source></video></p>\n\n<p>Step-by-step:</p>\n\n<ol>\n<li>Collapse both inner stack views in the <em>Document Outline</em>.</li>\n<li>Select any inner stack view in the <em>Document Outline</em>.</li>\n<li>With the previous inner stack view selected, shift-click the other inner stack view to select both inner stack views simultaneously.</li>\n<li>With both inner stack views selected, click on the <code>Embed In Stack</code> button.</li>\n<li>(Optional) If you look in your <em>Document Outline</em>, you can see your new outer stack view and it's subviews.</li>\n</ol>\n</div><p>Your storyboard should now look like the following:</p><p><a href=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P4-Implementing-Subviews/assets/outer_stack_view_unstyled.png\" target=\"_blank\">\n          <img src=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P4-Implementing-Subviews/assets/outer_stack_view_unstyled.png\" alt=\"Outer Stack View Unstyled\" title=\"\">\n        </a></p><p>With our inner and outer stack view constraints created, we'll need to add a few more constraints so <em>auto-layout</em> can determine each stack view's frame.</p><p>Let's start with remaining outer stack view constraints.</p><div class=\"action\">\n<p>\nSet the outer stack view's frame with the following constraints:</p>\n\n<p><video width=\"100%\" controls><source src=\"https://s3.amazonaws.com/mgwu-misc/Tip+Calculator+Swift+4/p4_implementing_subviews/add_outer_stack_view_constraints.mp4\" type=\"video/mp4\"></source></video></p>\n\n<p>Step-by-step:</p>\n\n<ol>\n<li>Select the outer stack view in the <em>Document Outline</em>.</li>\n<li>With your outer stack view selected, click the <code>Add New Constraints</code> button.</li>\n<li>Add the following two constraints using the <code>Add New Constraints</code> popup:\n\n<ul>\n<li>(Outer Stack View) Leading Edge 22pts from Super View (input card) Leading Edge</li>\n<li>(Outer Stack View) Trailing Edge 22pts from Super View Trailing Edge</li>\n</ul>\n</li>\n<li>In the <em>Document Outline</em>, hold down control (ctrl) and click-drag from the outer stack view to it's super view (input card).</li>\n<li>In the popup, select <code>Center Vertically In Container</code> to create a new constraint. This will vertically align the outer stack view's center with it's super view's center.</li>\n</ol>\n</div><p>Next, we'll add our equal width constraints to make sure the width of our outer and inner stack views are equal.</p><h3>Equal Widths Constraints</h3><div class=\"action\">\n<p>\nSet equal widths constraints for each stack view:</p>\n\n<p><video width=\"100%\" controls><source src=\"https://s3.amazonaws.com/mgwu-misc/Tip+Calculator+Swift+4/p4_implementing_subviews/add_stack_view_equal_widths_constraints.mp4\" type=\"video/mp4\"></source></video></p>\n\n<p>Step-by-step:</p>\n\n<ol>\n<li>Collapse both inner stack views in the <em>Document Outline</em>.</li>\n<li>Select the outer stack view in the <em>Document Outline</em>.</li>\n<li>With the outer stack view selected, shift-click the bottom inner stack view to select all three stack views simultaneously.</li>\n<li>With all stack views selected, click the <code>Add New Constraints</code> button.</li>\n<li>Select the <code>Equal Widths</code> checkbox and click <code>Add 2 Constraints</code> to create your equal width constraints.</li>\n</ol>\n</div><p>Our progress so far:</p><p><a href=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P4-Implementing-Subviews/assets/stack_view_equal_widths_unstyled.png\" target=\"_blank\">\n          <img src=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P4-Implementing-Subviews/assets/stack_view_equal_widths_unstyled.png\" alt=\"Stack View Equal Widths Unstyled\" title=\"\">\n        </a></p><p>Let's add our final width constraints for our text field and segmented control respectively.</p><h3>Fixed Width Constraints</h3><div class=\"action\">\n<p>\nSet a width constraint for the <em>Bill Amount Text Field</em>:</p>\n\n<p><video width=\"100%\" controls><source src=\"https://s3.amazonaws.com/mgwu-misc/Tip+Calculator+Swift+4/p4_implementing_subviews/text_field_width_constraint.mp4\" type=\"video/mp4\"></source></video></p>\n\n<p>Step-by-step:</p>\n\n<ol>\n<li>Select the <code>UITextField</code> object in the <em>Document Outline</em>.</li>\n<li>With the text field selected, click the <code>Add New Constraints</code> button.</li>\n<li>Set a fixed width constraint of 118pts.</li>\n</ol>\n</div><p>Finally, we'll need to add a fixed width constraint for our <code>UISegmentedControl</code>. Try to see if you can implement it by yourself.</p><div class=\"challenge\">\n<p>\nAdd a width constraint for your <em>Tip Percent Segmented Control</em> object. Set the width to 173pts. If you have trouble or get stuck, look at the previous example of adding a width constraint to our text field.</p>\n</div><p>Check your solution below.</p><div class=\"solution\">\n<p>\nWe set a width constraint for our <em>Tip Percent Segmented Control</em> with the following:</p>\n\n<p><video width=\"100%\" controls><source src=\"https://s3.amazonaws.com/mgwu-misc/Tip+Calculator+Swift+4/p4_implementing_subviews/segmented_control_width_constraint.mp4\" type=\"video/mp4\"></source></video></p>\n\n<p>Step-by-step:</p>\n\n<ol>\n<li>Select the <code>UISegmentedControl</code> object in the <em>Document Outline</em>.</li>\n<li>With the segmented control selected, click the <code>Add New Constraints</code> button.</li>\n<li>Set a fixed width constraint of 173pts.</li>\n</ol>\n</div><p>We've come a long ways from where we first started. We've finished adding all of our stack views and each view's constraints.</p><p><a href=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P4-Implementing-Subviews/assets/input_card_finished_constraints_unstyled.png\" target=\"_blank\">\n          <img src=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P4-Implementing-Subviews/assets/input_card_finished_constraints_unstyled.png\" alt=\"Input Card Finished Constraints Unstyled\" title=\"\">\n        </a></p><p>As you can see, our input card is starting to look more and more like our design. Next, we'll work on configuring our input card view attributes.</p><h2>Configuring Attributes</h2><p>At this point, you should be familiar with setting the attributes of a storyboard object using <em>Interface Builder</em>.</p><p>We'll quickly go through one together for review and let you do the rest on your own.</p><h3>Input Card Background Color</h3><div class=\"action\">\n<p>\nSet the <em>Input Card's</em> background color to <code>tcDarkBlue</code>:</p>\n\n<p><video width=\"100%\" controls><source src=\"https://s3.amazonaws.com/mgwu-misc/Tip+Calculator+Swift+4/p4_implementing_subviews/set_input_card_bg_color.mp4\" type=\"video/mp4\"></source></video></p>\n\n<p>Step-by-step:</p>\n\n<ol>\n<li>Select the input card view (<code>UIView</code>).</li>\n<li>Open the <em>Attributes Inspector</em> in the <em>Utilities area</em>.</li>\n<li>Find the <em>Background</em> attribute and use the blue dropdown button to change it's value from <code>White Color</code> to <code>tcDarkBlue</code>.</li>\n</ol>\n</div><p>Now it's your turn.</p><div class=\"challenge\">\n<p>\nSet each of the following attributes for each respective element:</p>\n\n<p><strong>Outer Stack View:</strong></p>\n\n<ul>\n<li>\n<em>Spacing</em>: Change from <code>0</code> to <code>35</code>\n</li>\n</ul>\n\n<p><strong>Bill Amount Title Label (Inner Top Stack View):</strong></p>\n\n<ul>\n<li>\n<em>Text</em>: Change from <code>Label</code> to <code>Bill Amount</code>\n</li>\n<li>\n<em>Font</em>: Change from <code>System 17.0</code> to <code>System 20.0</code>\n</li>\n<li>\n<em>Color</em>: Change from <code>Default</code> to <code>tcWhite</code>\n</li>\n<li>\n<em>Alignment</em>: Change from <code>---</code> to <code>Left Aligned</code>\n</li>\n</ul>\n\n<p><strong>Bill Amount Text Field (Inner Top Stack View):</strong></p>\n\n<ul>\n<li>\n<em>Alignment</em>: Change from <code>---</code> to <code>Center Aligned</code>\n</li>\n<li>\n<em>Placeholder</em>: Change from empty to <code>$0.00</code>\n</li>\n<li>\n<em>Correction</em>: Change from <code>Default</code> to <code>No</code>\n</li>\n<li>\n<em>Keyboard Type</em>: Change from <code>Default</code> to <code>Decimal Pad</code>\n</li>\n<li>\n<em>Keyboard Look</em>: Change from <code>Default</code> to <code>Light</code>\n</li>\n<li>\n<em>Tint</em>: Change from <code>Default</code> to <code>tcHotPink</code>\n</li>\n</ul>\n\n<p><strong>Tip Percent Title Label (Inner Bottom Stack View):</strong></p>\n\n<ul>\n<li>\n<em>Text</em>: Change from <code>Label</code> to <code>Tip %</code>\n</li>\n<li>\n<em>Font</em>: Change from <code>System 17.0</code> to <code>System 20.0</code>\n</li>\n<li>\n<em>Color</em>: Change from <code>Default</code> to <code>tcWhite</code>\n</li>\n<li>\n<em>Alignment</em>: Change from <code>---</code> to <code>Left Aligned</code>\n</li>\n</ul>\n\n<p><strong>Tip Percent Segmented Control (Inner Bottom Stack View):</strong></p>\n\n<ul>\n<li>\n<em>Segments</em>: Change from <code>2</code> to <code>3</code>\n</li>\n<li>\n<em>Tint</em>: Change from <code>Default</code> to <code>tcHotPink</code>\n</li>\n</ul>\n</div><p>The last attribute we'll need to set is the title for each segment our segmented control.</p><div class=\"action\">\n<p>\nFor each segment of your segmented control, set the title attribute to <code>15%</code>, <code>18%</code>, <code>20%</code> respectively:</p>\n\n<p><video width=\"100%\" controls><source src=\"https://s3.amazonaws.com/mgwu-misc/Tip+Calculator+Swift+4/p4_implementing_subviews/set_segmented_control_titles.mp4\" type=\"video/mp4\"></source></video></p>\n</div><p>Let's build and run our project to see our progress.</p><p><a href=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P4-Implementing-Subviews/assets/input_card_styled.png\" target=\"_blank\">\n          <img src=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P4-Implementing-Subviews/assets/input_card_styled.png\" alt=\"Input Card Styled\" title=\"\">\n        </a></p><p>Bam! Our app matches our design (with exception of the rounded corners of course).</p><div class=\"info\">\n<p>\nRounded corners (and shadows) make use of our view's layer property. We'll cover this later in this tutorial.</p>\n</div><p>Let's continue by creating the IB connections needed for our input card.</p><h2>Adding Our IB Connections</h2><p>We've done this before with our header view. Let's get some more practice creating IB connections.</p><p>We'll do another together for review.</p><p>Let's create an <code>IBOutlet</code> for our input card (<code>UIView</code>).</p><div class=\"action\">\n<p>\nCreate an <code>IBOutlet</code> for the input card view:</p>\n\n<p><video width=\"100%\" controls><source src=\"https://s3.amazonaws.com/mgwu-misc/Tip+Calculator+Swift+4/p4_implementing_subviews/input_card_ibaction.mp4\" type=\"video/mp4\"></source></video></p>\n\n<p>Step-by-step:</p>\n\n<ol>\n<li>Open <code>Main.storyboard</code> in your <em>Editor area</em>.</li>\n<li>Option-click on <code>ViewController.swift</code> in your <em>Project Navigator</em> to open it in your <em>Assitant Editor</em>.</li>\n<li>(Optional) Hide the <em>Utilities area</em> to make more screen space for the <em>Assistant Editor</em>.</li>\n<li>Select the input card view (<code>UIView</code>).</li>\n<li>With your input card selected, hold down control and click-drag from the input card to your <code>ViewController</code> class.</li>\n<li>In the popup, set the <em>Name</em> field to <code>inputCardView</code> and click connect to create your new outlet.</li>\n</ol>\n</div><!-- break --><div class=\"challenge\">\n<p>\nNow it's your turn to practice. If you find yourself stuck, look back on how we implemented our previous <code>IBOutlets</code> to refresh your memory.</p>\n\n<p>Create the following <code>IBOutlets</code>:</p>\n\n<ul>\n<li>\n<code>UITextField</code> named <code>billAmountTextField</code>\n</li>\n<li>\n<code>UISegmentedControl</code> named <code>tipPercentSegmentedControl</code>\n</li>\n</ul>\n</div><p>Finally, we'll need to create an <code>IBAction</code> for our segmented control.</p><div class=\"challenge\">\n<p>\nTry implementing an <code>IBAction</code> for your <code>UISegmentedControl</code>. Set the <em>Name</em> as <code>tipPercentChanged</code> and check that the <em>Event type</em> is <code>Value Changed</code>. If you get stuck, you can look back in the tutorial or check the solution (only if you're really stuck!)</p>\n</div><!-- break --><div class=\"solution\">\n<p>\nCreating an <code>IBAction</code> is similar to creating an <code>IBOutlet</code>:</p>\n\n<p><video width=\"100%\" controls><source src=\"https://s3.amazonaws.com/mgwu-misc/Tip+Calculator+Swift+4/p4_implementing_subviews/segmented_control_ibaction.mp4\" type=\"video/mp4\"></source></video></p>\n\n<p>Step-by-step:</p>\n\n<ol>\n<li>Select your segmented control (<code>UISegmentedControl</code>) in the <em>Document Outline</em>.</li>\n<li>With your segmented control selected, hold down ctrl and click-drag from the segmented control in your <em>Document Outline</em> to your <code>ViewController</code> class.</li>\n<li>You should see a popup for creating a new IB connection. In the popup, change the <em>Connection</em> type from <code>Outlet</code> to <code>Action</code>.</li>\n<li>Set the name of our action as <code>tipPercentChanged</code>.</li>\n<li>Change the <em>Type</em> property from <code>Any</code> to <code>UISegmentedControl</code>.</li>\n<li>Make sure the <em>Event</em> property is set as <code>Value Changed</code>. If not, use the dropdown to set it to <code>Value Changed</code>.</li>\n<li>Click <em>Connect</em> to create your new <code>IBAction</code>.</li>\n</ol>\n</div><p>When you're done, your storyboard and Swift code should look like the following:</p><p><a href=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P4-Implementing-Subviews/assets/input_card_ib_connections.png\" target=\"_blank\">\n          <img src=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P4-Implementing-Subviews/assets/input_card_ib_connections.png\" alt=\"Input Card IB Connections\" title=\"\">\n        </a></p><p>If everything looks right, on to the next! If something's off, let's go back in the tutorial and make sure we didn't accidentally skip any steps.</p><!-- TODO: add custom textfield, but don't do that here -->"},{"id":"T0E6OlNlY3Rpb24tMTE1","title":"Output Card View","htmlContent":"<p>We've gone through the process of implementing each of our subviews for two of the four UI groups. We'll need to do it once again. This time we'll be more hands-off to give you practice doing it yourself.</p><p>Let's take another look at our design:</p><p><a href=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P4-Implementing-Subviews/assets/output_card_design.png\" target=\"_blank\">\n          <img src=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P4-Implementing-Subviews/assets/output_card_design.png\" alt=\"Output Card Design\" title=\"\">\n        </a></p><p>For our output card, we'll need to add the following UI components:</p><p><a href=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P4-Implementing-Subviews/assets/tip_output_subviews.png\" target=\"_blank\">\n          <img src=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P4-Implementing-Subviews/assets/tip_output_subviews.png\" alt=\"Tip Output Subviews\" title=\"\">\n        </a></p><p>We'll need to add four new labels. Next, let's think about how we'll layout our views.</p><h2>Identifying Constraints</h2><p>Similar to our input card, we'll use a combination of stack views and constraints to implement our layout.</p><p><a href=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P4-Implementing-Subviews/assets/output_outer_stack_view.png\" target=\"_blank\">\n          <img src=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P4-Implementing-Subviews/assets/output_outer_stack_view.png\" alt=\"Output Outer Stack View\" title=\"\">\n        </a></p><p>First, we'll have two horizontal stack views:</p><ul>\n<li>(Inner Top Stack View) <em>Tip Amount Title Label</em> and <em>Tip Amount Label</em>\n</li>\n<li>(Inner Bottom Stack View) <em>Total Amount Title Label</em> and <em>Total Amount Label</em>\n</li>\n</ul><p>Next, we'll create a outer (vertical) stack view from the two inner stack views.</p><p>Just like the input card's outer stack view, we'll add the following constraints to set the frame of the outer stack view:</p><ul>\n<li>(Outer Stack View) Leading Edge 22pts from Super View (output card) Leading Edge</li>\n<li>(Outer Stack View) Trailing Edge 22pts from Super View Trailing Edge</li>\n<li>(Outer Stack View) Center vertically aligned with Super View Center</li>\n</ul><p>Finally, we'll add a few more constraints to make sure our subview widths are the correct size:</p><ul>\n<li>(Inner Top Stack View) Equal Width to Outer Stack View Width</li>\n<li>(Inner Bottom Stack View) Equal Width to Outer Stack View Width</li>\n<li>(Tip Amount Title Label) 110pts Width</li>\n<li>(Total Amount Title Label) 110pts Width</li>\n</ul><div class=\"info\">\n<p>\nLook back on how we implemented the input card for more details if you're wondering why we've added any of the constraints.</p>\n</div><h2>Adding Constraints</h2><p>We've already had practice with using stack views and constraints. This time, try practicing on your own. If you get stuck, look back on how we implemented the layout for our input card.</p><div class=\"challenge\">\n<p>\nCreate the inner top stack view with two <code>UILabel</code> views.</p>\n</div><!-- break --><div class=\"solution\">\n<p></p>\n\n<ol>\n<li>Drag two <code>UILabel</code> objects side-by-side from the <em>Object Library</em>.</li>\n<li>Select both labels and create a horizontal stack view.</li>\n</ol>\n</div><p>We'll also need to create the inner bottom stack view.</p><div class=\"challenge\">\n<p>\nCreate the inner bottom stack view with two <code>UILabel</code> views.</p>\n</div><!-- break --><div class=\"solution\">\n<p></p>\n\n<ol>\n<li>Drag two <code>UILabel</code> objects side-by-side from the <em>Object Library</em>. Make sure both labels are below the previous stack view.</li>\n<li>Select both labels and create a horizontal stack view.</li>\n</ol>\n</div><p>Next, let's create our outer stack view.</p><div class=\"challenge\">\n<p>\nCreate the <em>Outer Stack View</em> using both inner (horizontal) stack views.</p>\n</div><!-- break --><div class=\"solution\">\n<p></p>\n\n<ol>\n<li>Collapse and select both inner stack views in the <em>Document Outline</em>.</li>\n<li>With both inner stack views selected, click on the <code>Embed In Stack</code> button to create your outer stack view.</li>\n</ol>\n</div><p>Your storyboard should now look like the following:</p><p><a href=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P4-Implementing-Subviews/assets/output_card_outer_stack_view_unstyled.png\" target=\"_blank\">\n          <img src=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P4-Implementing-Subviews/assets/output_card_outer_stack_view_unstyled.png\" alt=\"Output Card Outer Stack View Unstyled\" title=\"\">\n        </a></p><p>Next, let's add the constraints for our outer stack view.</p><div class=\"challenge\">\n<p>\nSet the outer stack view's frame with the following constraints:</p>\n\n<ul>\n<li>(Outer Stack View) Leading Edge 22pts from Super View (output card) Leading Edge</li>\n<li>(Outer Stack View) Trailing Edge 22pts from Super View Trailing Edge</li>\n<li>(Outer Stack View) Center vertically aligned with Super View Center</li>\n</ul>\n</div><!-- break --><div class=\"solution\">\n<p></p>\n\n<ol>\n<li>Select the outer stack view in the <em>Document Outline</em>.</li>\n<li>With your outer stack view selected, click the <code>Add New Constraints</code> button.</li>\n<li>Add the following two constraints using the <code>Add New Constraints</code> popup:\n\n<ul>\n<li>(Outer Stack View) Leading Edge 22pts from Super View (output card) Leading Edge</li>\n<li>(Outer Stack View) Trailing Edge 22pts from Super View Trailing Edge</li>\n</ul>\n</li>\n<li>In the <em>Document Outline</em>, hold down control (ctrl) and click-drag from the outer stack view to it's super view (output card).</li>\n<li>In the popup, select <code>Center Vertically In Container</code> to create a new constraint. This will vertically align the outer stack view's center with it's super view's center.</li>\n</ol>\n</div><p>To finish up, we'll add the remaining width constraints.</p><div class=\"challenge\">\n<p>\nSet each of the width constraints for each respective view:</p>\n\n<ul>\n<li>(Inner Top Stack View) Equal Width to Outer Stack View Width</li>\n<li>(Inner Bottom Stack View) Equal Width to Outer Stack View Width</li>\n<li>(Tip Amount Title Label) 110pts Width</li>\n<li>(Total Amount Title Label) 110pts Width</li>\n</ul>\n</div><!-- break --><div class=\"solution\">\n<p>\nTo create both equal width constraints:</p>\n\n<ol>\n<li>Collapse both inner stack views in the <em>Document Outline</em>.</li>\n<li>Select the outer stack view in the <em>Document Outline</em>.</li>\n<li>With the outer stack view selected, shift-click the bottom inner stack view to select all three stack views simultaneously.</li>\n<li>With all stack views selected, click the <code>Add New Constraints</code> button.</li>\n<li>Select the <code>Equal Widths</code> checkbox and click <code>Add 2 Constraints</code> to create your equal width constraints.</li>\n</ol>\n\n<p>To create each title label's fixed width constraint:</p>\n\n<ol>\n<li>Select the <code>UILabel</code> object in the <em>Document Outline</em>. Make sure you're selecting the correct label.</li>\n<li>With the label selected, click the <code>Add New Constraints</code> button.</li>\n<li>Set a fixed width constraint of 110pts.</li>\n<li>Repeat the previous steps for the remaining title label.</li>\n</ol>\n</div><p>Whew! That was a lot of work in a short time. Nice job! When you're finished adding all stack views and view constraints your storyboard should look like the following:</p><p><a href=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P4-Implementing-Subviews/assets/output_card_finished_constraints_unstyled.png\" target=\"_blank\">\n          <img src=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P4-Implementing-Subviews/assets/output_card_finished_constraints_unstyled.png\" alt=\"Output Card Finished Constraints Unstyled\" title=\"\">\n        </a></p><p>Next, we'll configure our output card view attributes so that it matches our designs.</p><h2>Configuring Attributes</h2><div class=\"challenge\">\n<p>\nSet each of the following attributes for each respective element. Remember, if you get stuck you can look back to the previous steps in the tutorial for reference.</p>\n\n<p><strong>Output Card View:</strong></p>\n\n<ul>\n<li>\n<em>Background</em>: Change from <code>White Color</code> to <code>tcWhite</code>\n</li>\n</ul>\n\n<p><strong>Outer Stack View:</strong></p>\n\n<ul>\n<li>\n<em>Spacing</em>: Change from <code>0</code> to <code>35</code>\n</li>\n</ul>\n\n<p><strong>Tip Amount Title Label (Inner Top Stack View):</strong></p>\n\n<ul>\n<li>\n<em>Text</em>: Change from <code>Label</code> to <code>Tip Amount</code>\n</li>\n<li>\n<em>Font</em>: Change from <code>System 17.0</code> to <code>System Light 20.0</code>\n</li>\n<li>\n<em>Color</em>: Change from <code>Default</code> to <code>tcCharcoal</code>\n</li>\n<li>\n<em>Alignment</em>: Change from <code>---</code> to <code>Left Aligned</code>\n</li>\n</ul>\n\n<p><strong>Tip Amount Label (Inner Top Stack View):</strong></p>\n\n<ul>\n<li>\n<em>Text</em>: Change from <code>Label</code> to <code>$0.00</code>\n</li>\n<li>\n<em>Font</em>: Change from <code>System 17.0</code> to <code>System Medium 20.0</code>\n</li>\n<li>\n<em>Color</em>: Change from <code>Default</code> to <code>tcBlack</code>\n</li>\n<li>\n<em>Alignment</em>: Change from <code>---</code> to <code>Right Aligned</code>\n</li>\n</ul>\n\n<p><strong>Total Amount Title Label (Inner Bottom Stack View):</strong></p>\n\n<ul>\n<li>\n<em>Text</em>: Change from <code>Label</code> to <code>Total</code>\n</li>\n<li>\n<em>Font</em>: Change from <code>System 17.0</code> to <code>System Light 20.0</code>\n</li>\n<li>\n<em>Color</em>: Change from <code>Default</code> to <code>tcCharcoal</code>\n</li>\n<li>\n<em>Alignment</em>: Change from <code>---</code> to <code>Left Aligned</code>\n</li>\n</ul>\n\n<p><strong>Total Amount Label (Inner Bottom Stack View):</strong></p>\n\n<ul>\n<li>\n<em>Text</em>: Change from <code>Label</code> to <code>$0.00</code>\n</li>\n<li>\n<em>Font</em>: Change from <code>System 17.0</code> to <code>System Medium 20.0</code>\n</li>\n<li>\n<em>Color</em>: Change from <code>Default</code> to <code>tcBlack</code>\n</li>\n<li>\n<em>Alignment</em>: Change from <code>---</code> to <code>Right Aligned</code>\n</li>\n</ul>\n</div><p>Let's build and run our project to see our progress.</p><p><a href=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P4-Implementing-Subviews/assets/output_card_styled.png\" target=\"_blank\">\n          <img src=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P4-Implementing-Subviews/assets/output_card_styled.png\" alt=\"Output Card Styled\" title=\"\">\n        </a></p><p>Our app is really starting to come along! Let's finish by creating the IB connections needed for our output card.</p><h2>Adding Our IB Connections</h2><div class=\"challenge\">\n<p>\nAdd the following IB connections. If you find yourself stuck, look back on how we implemented our previous <code>IBOutlets</code> to refresh your memory.</p>\n\n<p>Use the diagram below for reference:</p>\n\n<p><a href=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P4-Implementing-Subviews/assets/tip_output_subviews.png\" target=\"_blank\">\n          <img src=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P4-Implementing-Subviews/assets/tip_output_subviews.png\" alt=\"Tip Output Subviews\" title=\"\">\n        </a></p>\n\n<p>Create the following <code>IBOutlets</code>:</p>\n\n<ul>\n<li>\n<code>UIView</code> named <code>outputCardView</code>\n</li>\n<li>\n<code>UILabel</code> named <code>tipAmountTitleLabel</code>\n</li>\n<li>\n<code>UILabel</code> named <code>tipAmountLabel</code>\n</li>\n<li>\n<code>UILabel</code> named <code>totalAmountTitleLabel</code>\n</li>\n<li>\n<code>UILabel</code> named <code>totalAmountLabel</code>\n</li>\n</ul>\n</div><p>When you're done, your storyboard and Swift code should look like the following:</p><p><a href=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P4-Implementing-Subviews/assets/output_card_ib_connections.png\" target=\"_blank\">\n          <img src=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P4-Implementing-Subviews/assets/output_card_ib_connections.png\" alt=\"Output Card IB Connections\" title=\"\">\n        </a></p>"},{"id":"T0E6OlNlY3Rpb24tMTE2","title":"Reset Button","htmlContent":"<p>Let's finish our last UI group: the reset button. Unlike the other UI groups, we won't need to add any subviews or extra constraints. We'll just need to styling our button and add it's IB connections.</p><h2>Configuring Attributes</h2><div class=\"challenge\">\n<p>\nYou know the drill. Set each of the following attributes for the reset button:</p>\n\n<p><strong>Reset Button:</strong></p>\n\n<ul>\n<li>\n<em>Type</em>: Change from <code>System</code> to <code>Custom</code>\n</li>\n<li>\n<em>Title</em>: Change from <code>Button</code> to <code>RESET</code>\n</li>\n<li>\n<em>Font</em>: Change from <code>System 15.0</code> to <code>System Bold 13.0</code>\n</li>\n<li>\n<em>Text Color</em>: Change from <code>Default</code> to <code>tcWhite</code>\n</li>\n</ul>\n</div><p>Your reset button should look like the following when you're done:</p><p><a href=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P4-Implementing-Subviews/assets/reset_button_styled.png\" target=\"_blank\">\n          <img src=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P4-Implementing-Subviews/assets/reset_button_styled.png\" alt=\"Reset Button Styled\" title=\"\">\n        </a></p><h2>Creating IB Connections</h2><p>Last, we'll need to add the button's IB connections.</p><div class=\"challenge\">\n<p>\nUse the <em>Assistant Editor</em> to add the following IB connections to your <code>ViewController</code> class:</p>\n\n<ol>\n<li>Create an <code>IBOutlet</code> for the reset button named <code>resetButton</code>.</li>\n<li>Create an <code>IBAction</code> for the reset button with the name <code>resetButtonTapped</code> with <em>Event type</em> of <code>Touch Up Inside</code>.</li>\n</ol>\n</div><p>When you're done, your storyboard and view controller source code should look like the following:</p><p><a href=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P4-Implementing-Subviews/assets/reset_button_ib_connections.png\" target=\"_blank\">\n          <img src=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P4-Implementing-Subviews/assets/reset_button_ib_connections.png\" alt=\"Reset Button IB Connections\" title=\"\">\n        </a></p><h3>Testing Our IBAction</h3><p>Let's make sure that our <code>IBAction</code> is working as expected.</p><div class=\"action\">\n<p>\nAdd a print statement in your <code>resetButtonTapped</code> function to test that it's working:</p>\n<pre><span class=\"nd\">@IBAction</span> <span class=\"n\">func</span> <span class=\"n\">resetButtonTapped</span><span class=\"p\">(</span><span class=\"n\">_</span> <span class=\"n\">sender</span><span class=\"p\">:</span> <span class=\"n\">UIButton</span><span class=\"p\">)</span> <span class=\"p\">{</span>\n    <span class=\"k\">print</span><span class=\"p\">(</span><span class=\"s2\">\"reset button tapped\"</span><span class=\"p\">)</span>\n<span class=\"p\">}</span>\n</pre>\n</div><p>Build and run your project. Tap the reset button a couple of times and verify that your print statement is being output to the debug console. Each time you tap the reset button, you should see the following:</p><p><a href=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P4-Implementing-Subviews/assets/reset_button_debug_print.png\" target=\"_blank\">\n          <img src=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P4-Implementing-Subviews/assets/reset_button_debug_print.png\" alt=\"Reset Button Debug Print\" title=\"\">\n        </a></p>"},{"id":"T0E6OlNlY3Rpb24tMTE3","title":"Conclusion","htmlContent":"<p>That's a wrap! We've learned a ton about implementing complex layouts with <em>auto-layout</em>, constraints and stack views. In the process, we've gotten a lot of practice and implemented the majority of our UI. In the next section, we'll work on implementing the logic for our tip calculator.</p>"}]},"next":{"id":"T0E6OlBhZ2UtNDA=","slug":"tip-calculator-logic","title":"Tip Calculator Logic"},"previous":{"id":"T0E6OlBhZ2UtNDA=","slug":"tip-calculator-logic","title":"Tip Calculator Logic"}},{"id":"T0E6OlBhZ2UtNDA=","title":"Tip Calculator Logic","slug":"tip-calculator-logic","sections":{"nodes":[{"id":"T0E6OlNlY3Rpb24tMTE4","title":"Tip Calculator Logic","htmlContent":"<p>At this point, we've finished building our tip calculator's UI. However, if we launch our app and try to use it, nothing happens. Hmm... not particularly useful.</p><p>To prevent one star reviews, let's make our tip calculator work by writing code that:</p><ol>\n<li>takes the user's input</li>\n<li>calculates the correct outputs</li>\n<li>updates the UI with the output data</li>\n</ol><p>Let's start by figuring out how to access our user's original bill amount as input!</p>"},{"id":"T0E6OlNlY3Rpb24tMTE5","title":"Reading Bill Amount Input","htmlContent":"<p>To calculate our output, we'll first need the user to input their original bill amount.</p><p><a href=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P5-Tip-Calculator-Logic/assets/bill_amount_input.png\" target=\"_blank\">\n          <img src=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P5-Tip-Calculator-Logic/assets/bill_amount_input.png\" alt=\"Bill Amount Input\" title=\"\">\n        </a></p><p>When the user taps on the <em>Bill Amount Text Field</em>, the decimal pad keyboard will be displayed for user input. However, after the user is done typing their bill amount, there's no way for them to dismiss the keyboard.</p><p>We'll fix this first, by implementing a <em>Calculate Button</em> that will appear right above the keyboard.</p><div class=\"info\">\n<p>\nTo keep things simple, there's a bit of <em>magic</em> that happens behind these scene for our soon-to-be calculate button. We've abstracted the majority into a custom <code>UITextField</code> subclass which will replace our current <code>UITextField</code>. Even if you don't fully understand how our calculate button is being displayed, bear with us for now!</p>\n</div><h2>Adding a Calculate Button</h2><div class=\"action\">\n<p>\nOpen <code>BillAmountTextField.swift</code> from your <em>Project Navigator</em>. You should see the following:</p>\n\n<p><a href=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P5-Tip-Calculator-Logic/assets/bill_amount_text_field_swift.png\" target=\"_blank\">\n          <img src=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P5-Tip-Calculator-Logic/assets/bill_amount_text_field_swift.png\" alt=\"Bill Amount Text Field Swift Code\" title=\"\">\n        </a></p>\n</div><p>The biggest thing to note, is that <code>BillAmountTextField.swift</code> is a custom subclass of <code>UITextField</code>. Our custom text field has an <em>input accessory view</em>, or a view that will be positioned just above the keyboard.</p><p>Don't worry too much about the code in this file for now. In short, it creates our <em>Calculate Button</em>, positions it within the's text field's <em>input accessory view</em>. We'll see that in a second.</p><p>To use our subclass, we'll need to replace our current <code>UITextField</code> with our <code>BillAmountTextField</code> subclass.</p><div class=\"action\">\n<p>\nOpen <code>Main.storyboard</code> and set <code>BillAmountTextField</code> as our <em>Bill Amount Text Field's</em> custom class:</p>\n\n<ol>\n<li>Select the <em>Bill Amount Text Field</em> using the <em>Document Outline</em>. <a href=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P5-Tip-Calculator-Logic/assets/select_text_field.png\" target=\"_blank\">\n          <img src=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P5-Tip-Calculator-Logic/assets/select_text_field.png\" alt=\"Select Text Field\" title=\"\">\n        </a>\n</li>\n<li>With the text field still selected, open the <em>Identity Inspector</em> in the <em>Utilities area</em>. <a href=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P5-Tip-Calculator-Logic/assets/open_identity_inspector.png\" target=\"_blank\">\n          <img src=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P5-Tip-Calculator-Logic/assets/open_identity_inspector.png\" alt=\"Open Identity Inspector\" title=\"\">\n        </a>\n</li>\n<li>In the <em>Identity Inspector</em>, find the <em>Class</em> field and set it to <code>BillAmountTextField</code>. As you start typing, auto-complete should complete the class you're looking for. If it doesn't, something's gone wrong! <a href=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P5-Tip-Calculator-Logic/assets/set_text_field_class.png\" target=\"_blank\">\n          <img src=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P5-Tip-Calculator-Logic/assets/set_text_field_class.png\" alt=\"Set Text Field Class\" title=\"\">\n        </a>\n</li>\n</ol>\n</div><p>Next, we'll need to update our text field's corresponding <code>IBOutlet</code> in our Swift code.</p><div class=\"action\">\n<p>\nOpen <code>ViewController.swift</code> and find the <code>IBOutlet</code> for your text field. Update your type of <code>billAmountTextField</code> from <code>UITextField</code> to <code>BillAmountTextField</code>:</p>\n<pre><span class=\"kd\">class</span> <span class=\"nc\">ViewController</span><span class=\"p\">:</span> <span class=\"bp\">UIViewController</span> <span class=\"p\">{</span>\n\n    <span class=\"c1\">// ...</span>\n\n    <span class=\"kr\">@IBOutlet</span> <span class=\"kr\">weak</span> <span class=\"kd\">var</span> <span class=\"nv\">billAmountTextField</span><span class=\"p\">:</span> <span class=\"n\">BillAmountTextField</span><span class=\"p\">!</span>\n\n    <span class=\"c1\">// ...</span>\n\n<span class=\"p\">}</span>\n</pre>\n</div><p>That's it! We've set our text field to a custom <code>UITextField</code> subclass. Let's test our changes.</p><div class=\"action\">\n<p>\nBuild and run your project. Tap on and select your <code>billAmountTextField</code>. The keyboard should slide up and you should see the following:</p>\n\n<p><a href=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P5-Tip-Calculator-Logic/assets/finished_custom_text_field.png\" target=\"_blank\">\n          <img src=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P5-Tip-Calculator-Logic/assets/finished_custom_text_field.png\" alt=\"Finished Custom Text Field\" title=\"\">\n        </a></p>\n</div><p>Do you see it? Right above the keyboard, you can see our new calculate button!</p><h2>Calculate Button Action</h2><p>Next, we'll need to figure out a way to execute code when the <em>Calculate Button</em> is tapped.</p><p>Open <code>BillAmountTextField.swift</code> from your <em>Project Navigator</em>.</p><p>Look for the <code>calculateButtonAction</code> property:</p><pre><span class=\"kd\">class</span> <span class=\"nc\">BillAmountTextField</span><span class=\"p\">:</span> <span class=\"bp\">UITextField</span> <span class=\"p\">{</span>\n\n    <span class=\"c1\">// ...</span>\n\n    <span class=\"kd\">var</span> <span class=\"nv\">calculateButtonAction</span><span class=\"p\">:</span> <span class=\"p\">(()</span> <span class=\"p\">-&gt;</span> <span class=\"nb\">Void</span><span class=\"p\">)?</span>\n\n    <span class=\"c1\">// ...</span>\n\n<span class=\"p\">}</span>\n</pre><p><code>calculateButtonAction</code> is a optional closure of type <code>(() -&gt; Void)?</code>. Next, if you look for the <code>calculateButtonTapped(_:)</code> function, you'll see that <code>calculateButtonAction</code> is called each time the <em>Calculate Button</em> is tapped:</p><pre><span class=\"kd\">class</span> <span class=\"nc\">BillAmountTextField</span><span class=\"p\">:</span> <span class=\"bp\">UITextField</span> <span class=\"p\">{</span>\n\n    <span class=\"c1\">// ...</span>\n\n    <span class=\"kr\">@objc</span> <span class=\"kd\">private</span> <span class=\"kd\">func</span> <span class=\"nf\">calculateButtonTapped</span><span class=\"p\">(</span><span class=\"kc\">_</span> <span class=\"n\">sender</span><span class=\"p\">:</span> <span class=\"bp\">UIBarButtonItem</span><span class=\"p\">)</span> <span class=\"p\">{</span>\n        <span class=\"n\">calculateButtonAction</span><span class=\"p\">?()</span>\n    <span class=\"p\">}</span>\n<span class=\"p\">}</span>\n</pre><p>By setting the <code>calculateButtonAction</code> property of our custom text field, we can pass a closure that is executed each time the <em>Calculate Button</em> is tapped.</p><div class=\"info\">\n<p>\nYou might be scratching your head, wondering how <code>calculateButtonTapped(_:)</code> is set up to be called each time the <em>Calculate Button</em> is tapped. We won't dive into too much details in this tutorial, but in short we've setup the equivalent <code>IBAction</code> programmatically with the following line of code:</p>\n<pre><span class=\"n\">let</span> <span class=\"n\">calculateButton</span> <span class=\"o\">=</span> <span class=\"bp\">UIBarButtonItem</span><span class=\"p\">(</span><span class=\"nl\">title</span><span class=\"p\">:</span> <span class=\"s\">\"Calculate Tip\"</span><span class=\"p\">,</span> <span class=\"nl\">style</span><span class=\"p\">:</span> <span class=\"p\">.</span><span class=\"n\">done</span><span class=\"p\">,</span> <span class=\"nl\">target</span><span class=\"p\">:</span> <span class=\"nb\">self</span><span class=\"p\">,</span> <span class=\"nl\">action</span><span class=\"p\">:</span> <span class=\"err\">#</span><span class=\"n\">selector</span><span class=\"p\">(</span><span class=\"n\">calculateButtonTapped</span><span class=\"p\">))</span>\n</pre>\n</div><p>Let's work on setting <code>calculateButtonAction</code> to execute a closure with a print statement.</p><div class=\"action\">\n<p>\nOpen <code>ViewController.swift</code>. Add the following code to <code>viewDidLoad</code>:</p>\n<pre><span class=\"kr\">override</span> <span class=\"kd\">func</span> <span class=\"nf\">viewDidLoad</span><span class=\"p\">()</span> <span class=\"p\">{</span>\n    <span class=\"kc\">super</span><span class=\"p\">.</span><span class=\"n\">viewDidLoad</span><span class=\"p\">()</span>\n\n    <span class=\"c1\">// 1</span>\n    <span class=\"n\">billAmountTextField</span><span class=\"p\">.</span><span class=\"n\">calculateButtonAction</span> <span class=\"p\">=</span> <span class=\"p\">{</span>\n        <span class=\"c1\">// 2</span>\n        <span class=\"bp\">print</span><span class=\"p\">(</span><span class=\"s\">\"calculate button tapped\"</span><span class=\"p\">)</span>\n    <span class=\"p\">}</span>\n<span class=\"p\">}</span>\n</pre>\n<p>Step-by-step:</p>\n\n<ol>\n<li>We set the <code>calculateButtonAction</code> variable of our <code>billAmountTextField</code> object to a new closure. To refresh your memory, a closure is a nameless function.</li>\n<li>Within the closure, we can set any code we want to be executed when the closure is called. In this case, we add a simple print statement.</li>\n</ol>\n</div><!-- break --><div class=\"info\">\n<p>\n<strong>What is the <code>viewDidLoad</code> function and what does it do?</strong></p>\n\n<p><code>viewDidLoad</code> is one of many view controller lifecycle functions. These functions are inherited from the <code>UIViewController</code> object. Each lifecycle function defines important events such as a view controller appearing or disappearing from screen. In particular, <code>viewDidLoad</code> is called when the view controller's view hierarchy (the root view and it's subviews) are loaded into memory.</p>\n\n<p>Other common view controller lifecycle functions include:</p>\n<pre><span class=\"nx\">func</span> <span class=\"nx\">viewWillAppear</span><span class=\"p\">(</span><span class=\"nx\">_</span> <span class=\"nx\">animated</span><span class=\"o\">:</span> <span class=\"nx\">Bool</span><span class=\"p\">)</span> <span class=\"c1\">// Called when the view is about to made visible. Default does nothing</span>\n\n<span class=\"nx\">func</span> <span class=\"nx\">viewDidAppear</span><span class=\"p\">(</span><span class=\"nx\">_</span> <span class=\"nx\">animated</span><span class=\"o\">:</span> <span class=\"nx\">Bool</span><span class=\"p\">)</span> <span class=\"c1\">// Called when the view has been fully transitioned onto the screen. Default does nothing</span>\n\n<span class=\"nx\">func</span> <span class=\"nx\">viewWillDisappear</span><span class=\"p\">(</span><span class=\"nx\">_</span> <span class=\"nx\">animated</span><span class=\"o\">:</span> <span class=\"nx\">Bool</span><span class=\"p\">)</span> <span class=\"c1\">// Called when the view is dismissed, covered or otherwise hidden. Default does nothing</span>\n\n<span class=\"nx\">func</span> <span class=\"nx\">viewDidDisappear</span><span class=\"p\">(</span><span class=\"nx\">_</span> <span class=\"nx\">animated</span><span class=\"o\">:</span> <span class=\"nx\">Bool</span><span class=\"p\">)</span> <span class=\"c1\">// Called after the view was dismissed, covered or otherwise hidden. Default does nothing</span>\n\n<span class=\"nx\">func</span> <span class=\"nx\">viewDidLayoutSubviews</span><span class=\"p\">()</span> <span class=\"c1\">// Called just after the view controller's view's layoutSubviews method is invoked. Subclasses can implement as necessary. The default is a nop.</span>\n</pre>\n<p>For our case, <code>viewDidLoad</code> is useful for calling any setup code that we want to happen the first time the view controller's view loads.</p>\n</div><p>Let's test that the closure we've set in our <code>viewDidLoad</code> method is called after tapping the <em>Calculate Button</em>.</p><div class=\"action\">\n<p>\nBuild and run your project:</p>\n\n<ol>\n<li>Tap on and select your <code>billAmountTextField</code>.</li>\n<li>Tap on the <em>Calculate Button</em> above your keyboard.</li>\n</ol>\n\n<p>After tapping the <em>Calculate Button</em> a couple times, check that the print statement appears in your debug console.</p>\n\n<p><a href=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P5-Tip-Calculator-Logic/assets/calculate_button_console_print.png\" target=\"_blank\">\n          <img src=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P5-Tip-Calculator-Logic/assets/calculate_button_console_print.png\" alt=\"Calculate Button Console Print\" title=\"\">\n        </a></p>\n</div><p>Nice! So far, we've successfully executing our print statement each time the <em>Calculate Button</em> is tapped. Last, let's change our print statement to print out the actual bill amount that the user has input in the <em>Bill Amount Text Field</em>.</p><h2>Accessing Text Field Input</h2><p>Just like all our other view objects, the <code>UITextField</code> is a class with many instance variables and functions. Since our <code>BillAmountTextField</code> is a custom subclass of <code>UITextField</code> it inherits all of it's instance functions and variables.</p><pre><span class=\"nx\">open</span> <span class=\"kr\">class</span> <span class=\"nx\">UITextField</span> <span class=\"o\">:</span> <span class=\"nx\">UIControl</span><span class=\"p\">,</span> <span class=\"nx\">UITextInput</span><span class=\"p\">,</span> <span class=\"nx\">NSCoding</span><span class=\"p\">,</span> <span class=\"nx\">UIContentSizeCategoryAdjusting</span> <span class=\"p\">{</span>\n\n    <span class=\"nx\">open</span> <span class=\"kd\">var</span> <span class=\"nx\">text</span><span class=\"o\">:</span> <span class=\"nb\">String</span><span class=\"o\">?</span>\n\n    <span class=\"err\">@</span><span class=\"nx\">available</span><span class=\"p\">(</span><span class=\"nx\">iOS</span> <span class=\"mf\">6.0</span><span class=\"p\">,</span> <span class=\"o\">*</span><span class=\"p\">)</span>\n    <span class=\"err\">@</span><span class=\"nx\">NSCopying</span> <span class=\"nx\">open</span> <span class=\"kd\">var</span> <span class=\"nx\">attributedText</span><span class=\"o\">:</span> <span class=\"nx\">NSAttributedString</span><span class=\"o\">?</span>\n\n    <span class=\"nx\">open</span> <span class=\"kd\">var</span> <span class=\"nx\">textColor</span><span class=\"o\">:</span> <span class=\"nx\">UIColor</span><span class=\"o\">?</span>\n\n    <span class=\"nx\">open</span> <span class=\"kd\">var</span> <span class=\"nx\">font</span><span class=\"o\">:</span> <span class=\"nx\">UIFont</span><span class=\"o\">?</span>\n\n    <span class=\"c1\">// ...</span>\n<span class=\"p\">}</span>\n</pre><p>Looking at the class definition of <code>UITextField</code>, you can see that accessing the text within a text field is a simple as reading it's <code>text</code> variable.</p><p>Let's try it out!</p><div class=\"action\">\n<p>\nChange the code in your <code>viewDidLoad</code> to the following:</p>\n<pre><span class=\"kr\">override</span> <span class=\"kd\">func</span> <span class=\"nf\">viewDidLoad</span><span class=\"p\">()</span> <span class=\"p\">{</span>\n    <span class=\"kc\">super</span><span class=\"p\">.</span><span class=\"n\">viewDidLoad</span><span class=\"p\">()</span>\n\n    <span class=\"n\">billAmountTextField</span><span class=\"p\">.</span><span class=\"n\">calculateButtonAction</span> <span class=\"p\">=</span> <span class=\"p\">{</span>\n        <span class=\"k\">guard</span> <span class=\"kd\">let</span> <span class=\"nv\">billAmountText</span> <span class=\"p\">=</span> <span class=\"kc\">self</span><span class=\"p\">.</span><span class=\"n\">billAmountTextField</span><span class=\"p\">.</span><span class=\"n\">text</span>\n            <span class=\"k\">else</span> <span class=\"p\">{</span> <span class=\"k\">return</span> <span class=\"p\">}</span>\n\n        <span class=\"bp\">print</span><span class=\"p\">(</span><span class=\"s\">\"Bill Amount: </span><span class=\"si\">\\(</span><span class=\"n\">billAmountText</span><span class=\"si\">)</span><span class=\"s\">\"</span><span class=\"p\">)</span>\n    <span class=\"p\">}</span>\n<span class=\"p\">}</span>\n</pre>\n<p>Notice in the code above, we use the <code>guard</code> keyboard to make sure <code>text</code> is a non-nil value. If the <code>text</code> value of our <code>billAmountTextField</code> is <code>nil</code>, the <code>guard</code> statement will return and the rest of the code in our closure won't be executed.</p>\n\n<p>Let's test our code again.</p>\n\n<ol>\n<li>Tap on and select your <code>billAmountTextField</code>.</li>\n<li>Type a bill amount on the decimal pad keyboard.</li>\n<li>Tap on the <em>Calculate Button</em>.</li>\n<li>Check that the correct bill amount is printed in your debug console.</li>\n</ol>\n\n<p><a href=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P5-Tip-Calculator-Logic/assets/bill_amount_console_print.png\" target=\"_blank\">\n          <img src=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P5-Tip-Calculator-Logic/assets/bill_amount_console_print.png\" alt=\"Bill Amount Console Print\" title=\"\">\n        </a></p>\n</div><p>As you can see, the correct bill amount now prints in our debug console!</p>"},{"id":"T0E6OlNlY3Rpb24tMTIw","title":"Calculating Tip","htmlContent":"<p>Now that we've successfully read our user's bill amount input, we're going to implement the logic to calculate our outputs (tip amount + total amount).</p><p>To calculate our outputs, we'll need to do the following:</p><ol>\n<li>Convert bill amount input from <code>String</code> to <code>Double</code>. The <em>Bill Amount</em> value should be rounded to the 2 nearest decimal places.</li>\n<li>Calculate the tip amount by multiplying the bill amount and tip percent. The tip amount should also be rounded to the 2 nearest decimal places.</li>\n<li>Calculate the total amount by adding together the bill and tip amounts.</li>\n</ol><p>First, let's convert our bill amount input value from a <code>String</code> to a <code>Double</code>. We can do this using Swift's built-in type initializers.</p><p>Let's take a a look:</p><div class=\"action\">\n<p>\nOpen <code>ViewController.swift</code> and change <code>viewDidLoad</code> to the following:</p>\n<pre><span class=\"kr\">override</span> <span class=\"kd\">func</span> <span class=\"nf\">viewDidLoad</span><span class=\"p\">()</span> <span class=\"p\">{</span>\n    <span class=\"kc\">super</span><span class=\"p\">.</span><span class=\"n\">viewDidLoad</span><span class=\"p\">()</span>\n\n    <span class=\"n\">billAmountTextField</span><span class=\"p\">.</span><span class=\"n\">calculateButtonAction</span> <span class=\"p\">=</span> <span class=\"p\">{</span>\n        <span class=\"c1\">// 1</span>\n        <span class=\"k\">guard</span> <span class=\"kd\">let</span> <span class=\"nv\">billAmountText</span> <span class=\"p\">=</span> <span class=\"kc\">self</span><span class=\"p\">.</span><span class=\"n\">billAmountTextField</span><span class=\"p\">.</span><span class=\"n\">text</span><span class=\"p\">,</span>\n            <span class=\"kd\">let</span> <span class=\"nv\">billAmount</span> <span class=\"p\">=</span> <span class=\"nb\">Double</span><span class=\"p\">(</span><span class=\"n\">billAmountText</span><span class=\"p\">)</span> <span class=\"k\">else</span> <span class=\"p\">{</span>\n                <span class=\"k\">return</span>\n        <span class=\"p\">}</span>\n\n        <span class=\"bp\">print</span><span class=\"p\">(</span><span class=\"s\">\"Bill Amount: </span><span class=\"si\">\\(</span><span class=\"n\">billAmount</span><span class=\"si\">)</span><span class=\"s\">\"</span><span class=\"p\">)</span>\n    <span class=\"p\">}</span>\n<span class=\"p\">}</span>\n</pre>\n</div><p>As you can see, Swift provides us with type initializers that allow us to easily convert from one type to another. In this case, we use the <code>Double(_:)</code> initializer to convert our <code>billAmountText</code> value from <code>String</code> to <code>Double</code>. If the string is an invalid value that can't be converted to a double, our initializer will fail and return nil.</p><p>Next, let's clean up our bill amount input by rounding the value to the nearest two decimal places. We can use the <code>rounded()</code> function on type <code>Double</code> like the following:</p><div class=\"action\">\n<p>\nSanitize the bill amount value by rounding to the nearest 2 decimal places:</p>\n<pre><span class=\"kr\">override</span> <span class=\"kd\">func</span> <span class=\"nf\">viewDidLoad</span><span class=\"p\">()</span> <span class=\"p\">{</span>\n    <span class=\"kc\">super</span><span class=\"p\">.</span><span class=\"n\">viewDidLoad</span><span class=\"p\">()</span>\n\n    <span class=\"n\">billAmountTextField</span><span class=\"p\">.</span><span class=\"n\">calculateButtonAction</span> <span class=\"p\">=</span> <span class=\"p\">{</span>\n        <span class=\"c1\">// 1</span>\n        <span class=\"k\">guard</span> <span class=\"kd\">let</span> <span class=\"nv\">billAmountText</span> <span class=\"p\">=</span> <span class=\"kc\">self</span><span class=\"p\">.</span><span class=\"n\">billAmountTextField</span><span class=\"p\">.</span><span class=\"n\">text</span><span class=\"p\">,</span>\n            <span class=\"kd\">let</span> <span class=\"nv\">billAmount</span> <span class=\"p\">=</span> <span class=\"nb\">Double</span><span class=\"p\">(</span><span class=\"n\">billAmountText</span><span class=\"p\">)</span> <span class=\"k\">else</span> <span class=\"p\">{</span>\n                <span class=\"k\">return</span>\n        <span class=\"p\">}</span>\n\n        <span class=\"kd\">let</span> <span class=\"nv\">roundedBillAmount</span> <span class=\"p\">=</span> <span class=\"p\">(</span><span class=\"mi\">100</span> <span class=\"o\">*</span> <span class=\"n\">billAmount</span><span class=\"p\">).</span><span class=\"n\">rounded</span><span class=\"p\">()</span> <span class=\"o\">/</span> <span class=\"mi\">100</span>\n\n        <span class=\"bp\">print</span><span class=\"p\">(</span><span class=\"s\">\"Bill Amount: </span><span class=\"si\">\\(</span><span class=\"n\">roundedBillAmount</span><span class=\"si\">)</span><span class=\"s\">\"</span><span class=\"p\">)</span>\n    <span class=\"p\">}</span>\n<span class=\"p\">}</span>\n</pre>\n</div><p>With our correctly formatted bill amount, we can calculate the tip amount of the bill. To start, let's use a fixed tip percent of 15%. While we're at it, let's also sanitize our tip amount by rounding to the nearest 2 decimal places.</p><div class=\"info\">\n<p>\nIn the future, we'll use the segmented control to allow the user to select a dynamic tip percent.</p>\n</div><!-- break --><div class=\"action\">\n<p>\nCalculate and sanitize the tip amount:</p>\n<pre><span class=\"kr\">override</span> <span class=\"kd\">func</span> <span class=\"nf\">viewDidLoad</span><span class=\"p\">()</span> <span class=\"p\">{</span>\n    <span class=\"kc\">super</span><span class=\"p\">.</span><span class=\"n\">viewDidLoad</span><span class=\"p\">()</span>\n\n    <span class=\"n\">billAmountTextField</span><span class=\"p\">.</span><span class=\"n\">calculateButtonAction</span> <span class=\"p\">=</span> <span class=\"p\">{</span>\n        <span class=\"c1\">// 1</span>\n        <span class=\"k\">guard</span> <span class=\"kd\">let</span> <span class=\"nv\">billAmountText</span> <span class=\"p\">=</span> <span class=\"kc\">self</span><span class=\"p\">.</span><span class=\"n\">billAmountTextField</span><span class=\"p\">.</span><span class=\"n\">text</span><span class=\"p\">,</span>\n            <span class=\"kd\">let</span> <span class=\"nv\">billAmount</span> <span class=\"p\">=</span> <span class=\"nb\">Double</span><span class=\"p\">(</span><span class=\"n\">billAmountText</span><span class=\"p\">)</span> <span class=\"k\">else</span> <span class=\"p\">{</span>\n                <span class=\"k\">return</span>\n        <span class=\"p\">}</span>\n\n        <span class=\"kd\">let</span> <span class=\"nv\">roundedBillAmount</span> <span class=\"p\">=</span> <span class=\"p\">(</span><span class=\"mi\">100</span> <span class=\"o\">*</span> <span class=\"n\">billAmount</span><span class=\"p\">).</span><span class=\"n\">rounded</span><span class=\"p\">()</span> <span class=\"o\">/</span> <span class=\"mi\">100</span>\n\n        <span class=\"c1\">// 2</span>\n        <span class=\"kd\">let</span> <span class=\"nv\">tipPercent</span> <span class=\"p\">=</span> <span class=\"mf\">0.15</span>\n        <span class=\"kd\">let</span> <span class=\"nv\">tipAmount</span> <span class=\"p\">=</span> <span class=\"n\">roundedBillAmount</span> <span class=\"o\">*</span> <span class=\"n\">tipPercent</span>\n        <span class=\"kd\">let</span> <span class=\"nv\">roundedTipAmount</span> <span class=\"p\">=</span> <span class=\"p\">(</span><span class=\"mi\">100</span> <span class=\"o\">*</span> <span class=\"n\">tipAmount</span><span class=\"p\">).</span><span class=\"n\">rounded</span><span class=\"p\">()</span> <span class=\"o\">/</span> <span class=\"mi\">100</span>\n\n        <span class=\"bp\">print</span><span class=\"p\">(</span><span class=\"s\">\"Bill Amount: </span><span class=\"si\">\\(</span><span class=\"n\">roundedBillAmount</span><span class=\"si\">)</span><span class=\"s\">\"</span><span class=\"p\">)</span>\n        <span class=\"bp\">print</span><span class=\"p\">(</span><span class=\"s\">\"Tip Amount: </span><span class=\"si\">\\(</span><span class=\"n\">roundedTipAmount</span><span class=\"si\">)</span><span class=\"s\">\"</span><span class=\"p\">)</span>\n    <span class=\"p\">}</span>\n<span class=\"p\">}</span>\n</pre>\n</div><p>To wrap up our logic, we can calculate our total amount by adding together our tip and bill amounts.</p><div class=\"action\">\n<p>\nCalculate the total amount:</p>\n<pre><span class=\"kr\">override</span> <span class=\"kd\">func</span> <span class=\"nf\">viewDidLoad</span><span class=\"p\">()</span> <span class=\"p\">{</span>\n    <span class=\"kc\">super</span><span class=\"p\">.</span><span class=\"n\">viewDidLoad</span><span class=\"p\">()</span>\n\n    <span class=\"n\">billAmountTextField</span><span class=\"p\">.</span><span class=\"n\">calculateButtonAction</span> <span class=\"p\">=</span> <span class=\"p\">{</span>\n        <span class=\"c1\">// 1</span>\n        <span class=\"k\">guard</span> <span class=\"kd\">let</span> <span class=\"nv\">billAmountText</span> <span class=\"p\">=</span> <span class=\"kc\">self</span><span class=\"p\">.</span><span class=\"n\">billAmountTextField</span><span class=\"p\">.</span><span class=\"n\">text</span><span class=\"p\">,</span>\n            <span class=\"kd\">let</span> <span class=\"nv\">billAmount</span> <span class=\"p\">=</span> <span class=\"nb\">Double</span><span class=\"p\">(</span><span class=\"n\">billAmountText</span><span class=\"p\">)</span> <span class=\"k\">else</span> <span class=\"p\">{</span>\n                <span class=\"k\">return</span>\n        <span class=\"p\">}</span>\n\n        <span class=\"kd\">let</span> <span class=\"nv\">roundedBillAmount</span> <span class=\"p\">=</span> <span class=\"p\">(</span><span class=\"mi\">100</span> <span class=\"o\">*</span> <span class=\"n\">billAmount</span><span class=\"p\">).</span><span class=\"n\">rounded</span><span class=\"p\">()</span> <span class=\"o\">/</span> <span class=\"mi\">100</span>\n\n        <span class=\"c1\">// 2</span>\n        <span class=\"kd\">let</span> <span class=\"nv\">tipPercent</span> <span class=\"p\">=</span> <span class=\"mf\">0.15</span>\n        <span class=\"kd\">let</span> <span class=\"nv\">tipAmount</span> <span class=\"p\">=</span> <span class=\"n\">roundedBillAmount</span> <span class=\"o\">*</span> <span class=\"n\">tipPercent</span>\n        <span class=\"kd\">let</span> <span class=\"nv\">roundedTipAmount</span> <span class=\"p\">=</span> <span class=\"p\">(</span><span class=\"mi\">100</span> <span class=\"o\">*</span> <span class=\"n\">tipAmount</span><span class=\"p\">).</span><span class=\"n\">rounded</span><span class=\"p\">()</span> <span class=\"o\">/</span> <span class=\"mi\">100</span>\n\n        <span class=\"c1\">// 3</span>\n        <span class=\"kd\">let</span> <span class=\"nv\">totalAmount</span> <span class=\"p\">=</span> <span class=\"n\">roundedBillAmount</span> <span class=\"o\">+</span> <span class=\"n\">roundedTipAmount</span>\n\n        <span class=\"bp\">print</span><span class=\"p\">(</span><span class=\"s\">\"Bill Amount: </span><span class=\"si\">\\(</span><span class=\"n\">roundedBillAmount</span><span class=\"si\">)</span><span class=\"s\">\"</span><span class=\"p\">)</span>\n        <span class=\"bp\">print</span><span class=\"p\">(</span><span class=\"s\">\"Tip Amount: </span><span class=\"si\">\\(</span><span class=\"n\">roundedTipAmount</span><span class=\"si\">)</span><span class=\"s\">\"</span><span class=\"p\">)</span>\n        <span class=\"bp\">print</span><span class=\"p\">(</span><span class=\"s\">\"Total Amount: </span><span class=\"si\">\\(</span><span class=\"n\">totalAmount</span><span class=\"si\">)</span><span class=\"s\">\"</span><span class=\"p\">)</span>\n    <span class=\"p\">}</span>\n<span class=\"p\">}</span>\n</pre>\n</div><p>Let's test our logic to see if it's working as expected.</p><div class=\"action\">\n<p>\nBuild and run your project. Test a couple values and verify that the print statements in the debug console are correct.</p>\n\n<p><a href=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P5-Tip-Calculator-Logic/assets/total_amount_print_console.png\" target=\"_blank\">\n          <img src=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P5-Tip-Calculator-Logic/assets/total_amount_print_console.png\" alt=\"Total Amount Print Console\" title=\"\">\n        </a></p>\n</div>"},{"id":"T0E6OlNlY3Rpb24tMTIx","title":"Setting The Output Card","htmlContent":"<p>We'll need to update the UI with the output values that we've calculated. But first, we'll need to dismiss the keyboard so it isn't covering the output card.</p><div class=\"action\">\n<p>\nIn <code>ViewController.swift</code>, add the following lines of code in <code>viewDidLoad</code>:</p>\n<pre><span class=\"n\">billAmountTextField</span><span class=\"p\">.</span><span class=\"n\">calculateButtonAction</span> <span class=\"p\">=</span> <span class=\"p\">{</span>\n    <span class=\"c1\">// dismiss keyboard if it's displayed</span>\n    <span class=\"k\">if</span> <span class=\"kc\">self</span><span class=\"p\">.</span><span class=\"n\">billAmountTextField</span><span class=\"p\">.</span><span class=\"n\">isFirstResponder</span> <span class=\"p\">{</span>\n        <span class=\"kc\">self</span><span class=\"p\">.</span><span class=\"n\">billAmountTextField</span><span class=\"p\">.</span><span class=\"n\">resignFirstResponder</span><span class=\"p\">()</span>\n    <span class=\"p\">}</span>\n\n    <span class=\"c1\">// ...</span>\n<span class=\"p\">}</span>\n</pre>\n</div><p>If you build and run your project again. Now, after tapping the <em>Calculate Button</em>, the keyboard will be dismissed.</p><p>Now that our output card is no longer being hidden, we can work on updating the UI.</p><p>If you take a look at the <code>UILabel</code> class definition, you'll see the following:</p><pre><span class=\"kd\">class</span> <span class=\"bp\">UILabel</span> <span class=\"p\">:</span> <span class=\"bp\">UIView</span><span class=\"p\">,</span> <span class=\"bp\">NSCoding</span><span class=\"p\">,</span> <span class=\"n\">UIContentSizeCategoryAdjusting</span> <span class=\"p\">{</span>\n\n    <span class=\"kd\">var</span> <span class=\"nv\">text</span><span class=\"p\">:</span> <span class=\"nb\">String</span><span class=\"p\">?</span>\n\n    <span class=\"kd\">var</span> <span class=\"nv\">font</span><span class=\"p\">:</span> <span class=\"bp\">UIFont</span><span class=\"p\">!</span>\n\n    <span class=\"kd\">var</span> <span class=\"nv\">textColor</span><span class=\"p\">:</span> <span class=\"bp\">UIColor</span><span class=\"p\">!</span>\n\n    <span class=\"c1\">// ...</span>\n\n<span class=\"p\">}</span>\n</pre><p>To update the text that a <code>UILabel</code> displays, we can use the <code>text</code> property of each <code>UILabel</code>. Let's update our <code>calculateButtonAction</code> closure so that it sets the output card's tip amount and total amount labels.</p><div class=\"action\">\n<p>\nIn <code>ViewController.swift</code>, update your code update the output card's labels:</p>\n<pre><span class=\"kr\">override</span> <span class=\"kd\">func</span> <span class=\"nf\">viewDidLoad</span><span class=\"p\">()</span> <span class=\"p\">{</span>\n    <span class=\"kc\">super</span><span class=\"p\">.</span><span class=\"n\">viewDidLoad</span><span class=\"p\">()</span>\n\n    <span class=\"n\">billAmountTextField</span><span class=\"p\">.</span><span class=\"n\">calculateButtonAction</span> <span class=\"p\">=</span> <span class=\"p\">{</span>\n        <span class=\"c1\">// dismiss keyboard if it's displayed</span>\n        <span class=\"k\">if</span> <span class=\"kc\">self</span><span class=\"p\">.</span><span class=\"n\">billAmountTextField</span><span class=\"p\">.</span><span class=\"n\">isFirstResponder</span> <span class=\"p\">{</span>\n            <span class=\"kc\">self</span><span class=\"p\">.</span><span class=\"n\">billAmountTextField</span><span class=\"p\">.</span><span class=\"n\">resignFirstResponder</span><span class=\"p\">()</span>\n        <span class=\"p\">}</span>\n\n        <span class=\"k\">guard</span> <span class=\"kd\">let</span> <span class=\"nv\">billAmountText</span> <span class=\"p\">=</span> <span class=\"kc\">self</span><span class=\"p\">.</span><span class=\"n\">billAmountTextField</span><span class=\"p\">.</span><span class=\"n\">text</span><span class=\"p\">,</span>\n            <span class=\"kd\">let</span> <span class=\"nv\">billAmount</span> <span class=\"p\">=</span> <span class=\"nb\">Double</span><span class=\"p\">(</span><span class=\"n\">billAmountText</span><span class=\"p\">)</span> <span class=\"k\">else</span> <span class=\"p\">{</span>\n                <span class=\"k\">return</span>\n        <span class=\"p\">}</span>\n\n        <span class=\"kd\">let</span> <span class=\"nv\">roundedBillAmount</span> <span class=\"p\">=</span> <span class=\"p\">(</span><span class=\"mi\">100</span> <span class=\"o\">*</span> <span class=\"n\">billAmount</span><span class=\"p\">).</span><span class=\"n\">rounded</span><span class=\"p\">()</span> <span class=\"o\">/</span> <span class=\"mi\">100</span>\n\n        <span class=\"kd\">let</span> <span class=\"nv\">tipPercent</span> <span class=\"p\">=</span> <span class=\"mf\">0.15</span>\n        <span class=\"kd\">let</span> <span class=\"nv\">tipAmount</span> <span class=\"p\">=</span> <span class=\"n\">roundedBillAmount</span> <span class=\"o\">*</span> <span class=\"n\">tipPercent</span>\n        <span class=\"kd\">let</span> <span class=\"nv\">roundedTipAmount</span> <span class=\"p\">=</span> <span class=\"p\">(</span><span class=\"mi\">100</span> <span class=\"o\">*</span> <span class=\"n\">tipAmount</span><span class=\"p\">).</span><span class=\"n\">rounded</span><span class=\"p\">()</span> <span class=\"o\">/</span> <span class=\"mi\">100</span>\n\n        <span class=\"kd\">let</span> <span class=\"nv\">totalAmount</span> <span class=\"p\">=</span> <span class=\"n\">roundedBillAmount</span> <span class=\"o\">+</span> <span class=\"n\">roundedTipAmount</span>\n\n        <span class=\"c1\">// Update UI</span>\n        <span class=\"kc\">self</span><span class=\"p\">.</span><span class=\"n\">billAmountTextField</span><span class=\"p\">.</span><span class=\"n\">text</span> <span class=\"p\">=</span> <span class=\"nb\">String</span><span class=\"p\">(</span><span class=\"n\">format</span><span class=\"p\">:</span> <span class=\"s\">\"%.2f\"</span><span class=\"p\">,</span> <span class=\"n\">roundedBillAmount</span><span class=\"p\">)</span>\n        <span class=\"kc\">self</span><span class=\"p\">.</span><span class=\"n\">tipAmountLabel</span><span class=\"p\">.</span><span class=\"n\">text</span> <span class=\"p\">=</span> <span class=\"nb\">String</span><span class=\"p\">(</span><span class=\"n\">format</span><span class=\"p\">:</span> <span class=\"s\">\"%.2f\"</span><span class=\"p\">,</span> <span class=\"n\">roundedTipAmount</span><span class=\"p\">)</span>\n        <span class=\"kc\">self</span><span class=\"p\">.</span><span class=\"n\">totalAmountLabel</span><span class=\"p\">.</span><span class=\"n\">text</span> <span class=\"p\">=</span> <span class=\"nb\">String</span><span class=\"p\">(</span><span class=\"n\">format</span><span class=\"p\">:</span> <span class=\"s\">\"%.2f\"</span><span class=\"p\">,</span> <span class=\"n\">totalAmount</span><span class=\"p\">)</span>\n    <span class=\"p\">}</span>\n<span class=\"p\">}</span>\n</pre>\n<p>The code we just added, updates the UI by setting each corresponding label's <code>text</code> property to a formatted string.</p>\n\n<p>Build and run your project. Input a bill amount and tap the <em>Calculate Button</em>. If it works, you should see your tip and bill amounts show up on the output card!</p>\n\n<p><a href=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P5-Tip-Calculator-Logic/assets/set_output_labels.png\" target=\"_blank\">\n          <img src=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P5-Tip-Calculator-Logic/assets/set_output_labels.png\" alt=\"Set Output Labels\" title=\"\">\n        </a></p>\n</div>"},{"id":"T0E6OlNlY3Rpb24tMTIy","title":"Refactoring Our Calculate Logic","htmlContent":"<p>Before moving on, let's refactor some of our existing code. Right now, the majority of our logic for calculating the tip and bill amounts are in our <code>calculateButtonAction</code> closure.</p><p>Let's move our logic out into it's own function so it can be re-used.</p><div class=\"action\">\n<p>\nIn <code>ViewController.swift</code>, create a new function for calculating tip:</p>\n<pre><span class=\"kd\">func</span> <span class=\"nf\">calculate</span><span class=\"p\">()</span> <span class=\"p\">{</span>\n    <span class=\"c1\">// dismiss keyboard</span>\n    <span class=\"k\">if</span> <span class=\"kc\">self</span><span class=\"p\">.</span><span class=\"n\">billAmountTextField</span><span class=\"p\">.</span><span class=\"n\">isFirstResponder</span> <span class=\"p\">{</span>\n        <span class=\"kc\">self</span><span class=\"p\">.</span><span class=\"n\">billAmountTextField</span><span class=\"p\">.</span><span class=\"n\">resignFirstResponder</span><span class=\"p\">()</span>\n    <span class=\"p\">}</span>\n\n    <span class=\"k\">guard</span> <span class=\"kd\">let</span> <span class=\"nv\">billAmountText</span> <span class=\"p\">=</span> <span class=\"kc\">self</span><span class=\"p\">.</span><span class=\"n\">billAmountTextField</span><span class=\"p\">.</span><span class=\"n\">text</span><span class=\"p\">,</span>\n        <span class=\"kd\">let</span> <span class=\"nv\">billAmount</span> <span class=\"p\">=</span> <span class=\"nb\">Double</span><span class=\"p\">(</span><span class=\"n\">billAmountText</span><span class=\"p\">)</span> <span class=\"k\">else</span> <span class=\"p\">{</span>\n            <span class=\"k\">return</span>\n    <span class=\"p\">}</span>\n\n    <span class=\"kd\">let</span> <span class=\"nv\">roundedBillAmount</span> <span class=\"p\">=</span> <span class=\"p\">(</span><span class=\"mi\">100</span> <span class=\"o\">*</span> <span class=\"n\">billAmount</span><span class=\"p\">).</span><span class=\"n\">rounded</span><span class=\"p\">()</span> <span class=\"o\">/</span> <span class=\"mi\">100</span>\n\n    <span class=\"kd\">let</span> <span class=\"nv\">tipPercent</span> <span class=\"p\">=</span> <span class=\"mf\">0.15</span>\n    <span class=\"kd\">let</span> <span class=\"nv\">tipAmount</span> <span class=\"p\">=</span> <span class=\"n\">roundedBillAmount</span> <span class=\"o\">*</span> <span class=\"n\">tipPercent</span>\n    <span class=\"kd\">let</span> <span class=\"nv\">roundedTipAmount</span> <span class=\"p\">=</span> <span class=\"p\">(</span><span class=\"mi\">100</span> <span class=\"o\">*</span> <span class=\"n\">tipAmount</span><span class=\"p\">).</span><span class=\"n\">rounded</span><span class=\"p\">()</span> <span class=\"o\">/</span> <span class=\"mi\">100</span>\n\n    <span class=\"kd\">let</span> <span class=\"nv\">totalAmount</span> <span class=\"p\">=</span> <span class=\"n\">roundedBillAmount</span> <span class=\"o\">+</span> <span class=\"n\">roundedTipAmount</span>\n\n    <span class=\"c1\">// Update UI</span>\n    <span class=\"kc\">self</span><span class=\"p\">.</span><span class=\"n\">billAmountTextField</span><span class=\"p\">.</span><span class=\"n\">text</span> <span class=\"p\">=</span> <span class=\"nb\">String</span><span class=\"p\">(</span><span class=\"n\">format</span><span class=\"p\">:</span> <span class=\"s\">\"%.2f\"</span><span class=\"p\">,</span> <span class=\"n\">roundedBillAmount</span><span class=\"p\">)</span>\n    <span class=\"kc\">self</span><span class=\"p\">.</span><span class=\"n\">tipAmountLabel</span><span class=\"p\">.</span><span class=\"n\">text</span> <span class=\"p\">=</span> <span class=\"nb\">String</span><span class=\"p\">(</span><span class=\"n\">format</span><span class=\"p\">:</span> <span class=\"s\">\"%.2f\"</span><span class=\"p\">,</span> <span class=\"n\">roundedTipAmount</span><span class=\"p\">)</span>\n    <span class=\"kc\">self</span><span class=\"p\">.</span><span class=\"n\">totalAmountLabel</span><span class=\"p\">.</span><span class=\"n\">text</span> <span class=\"p\">=</span> <span class=\"nb\">String</span><span class=\"p\">(</span><span class=\"n\">format</span><span class=\"p\">:</span> <span class=\"s\">\"%.2f\"</span><span class=\"p\">,</span> <span class=\"n\">totalAmount</span><span class=\"p\">)</span>\n<span class=\"p\">}</span>\n</pre>\n</div><p>Next, let's change our <code>calculateButtonAction</code> closure to use our <code>calculate</code> method.</p><div class=\"action\">\n<p>\nIn <code>ViewController.swift</code>, change <code>viewDidLoad</code> to the following:</p>\n<pre><span class=\"kr\">override</span> <span class=\"kd\">func</span> <span class=\"nf\">viewDidLoad</span><span class=\"p\">()</span> <span class=\"p\">{</span>\n    <span class=\"kc\">super</span><span class=\"p\">.</span><span class=\"n\">viewDidLoad</span><span class=\"p\">()</span>\n\n    <span class=\"n\">billAmountTextField</span><span class=\"p\">.</span><span class=\"n\">calculateButtonAction</span> <span class=\"p\">=</span> <span class=\"p\">{</span>\n        <span class=\"kc\">self</span><span class=\"p\">.</span><span class=\"n\">calculate</span><span class=\"p\">()</span>\n    <span class=\"p\">}</span>\n<span class=\"p\">}</span>\n</pre>\n</div><p>We've separated our logic into it's own function. This will help us as we implement our <code>UISegmentedControl</code>.</p>"},{"id":"T0E6OlNlY3Rpb24tMTIz","title":"Setting Tip Percent","htmlContent":"<p>Our UI is being correctly updated when we calculate our tip. Next, let's go back and implement our <code>UISegmentedControl</code>.</p><p>Currently, our view controller contains an <code>IBAction</code> that is triggered each time the user selects a new segment of the <code>UISegmentedControl</code>. When this <code>IBAction</code> is triggered, we want to re-calculate our tip using the new selected tip percent.</p><p>First, let's update our <code>IBAction</code> to calculate the tip whenever a segment is selected.</p><div class=\"action\">\n<p>\nIn <code>ViewController.swift</code>, update <code>tipPercentChanged(_:)</code> to the following:</p>\n<pre><span class=\"nd\">@IBAction</span> <span class=\"n\">func</span> <span class=\"n\">tipPercentChanged</span><span class=\"p\">(</span><span class=\"n\">_</span> <span class=\"n\">sender</span><span class=\"p\">:</span> <span class=\"n\">UISegmentedControl</span><span class=\"p\">)</span> <span class=\"p\">{</span>\n    <span class=\"n\">calculate</span><span class=\"p\">()</span>\n<span class=\"p\">}</span>\n</pre>\n</div><p>Next, we'll update our calculate function to use the correct tip percent of the <code>UISegmentedControl</code>.</p><div class=\"action\">\n<p>\nIn <code>ViewController.swift</code>, change the <code>calculate()</code> function to the following:</p>\n<pre><span class=\"kd\">func</span> <span class=\"nf\">calculate</span><span class=\"p\">()</span> <span class=\"p\">{</span>\n    <span class=\"c1\">// dismiss keyboard</span>\n    <span class=\"k\">if</span> <span class=\"kc\">self</span><span class=\"p\">.</span><span class=\"n\">billAmountTextField</span><span class=\"p\">.</span><span class=\"n\">isFirstResponder</span> <span class=\"p\">{</span>\n        <span class=\"kc\">self</span><span class=\"p\">.</span><span class=\"n\">billAmountTextField</span><span class=\"p\">.</span><span class=\"n\">resignFirstResponder</span><span class=\"p\">()</span>\n    <span class=\"p\">}</span>\n\n    <span class=\"k\">guard</span> <span class=\"kd\">let</span> <span class=\"nv\">billAmountText</span> <span class=\"p\">=</span> <span class=\"kc\">self</span><span class=\"p\">.</span><span class=\"n\">billAmountTextField</span><span class=\"p\">.</span><span class=\"n\">text</span><span class=\"p\">,</span>\n        <span class=\"kd\">let</span> <span class=\"nv\">billAmount</span> <span class=\"p\">=</span> <span class=\"nb\">Double</span><span class=\"p\">(</span><span class=\"n\">billAmountText</span><span class=\"p\">)</span> <span class=\"k\">else</span> <span class=\"p\">{</span>\n            <span class=\"k\">return</span>\n    <span class=\"p\">}</span>\n\n    <span class=\"kd\">let</span> <span class=\"nv\">roundedBillAmount</span> <span class=\"p\">=</span> <span class=\"p\">(</span><span class=\"mi\">100</span> <span class=\"o\">*</span> <span class=\"n\">billAmount</span><span class=\"p\">).</span><span class=\"n\">rounded</span><span class=\"p\">()</span> <span class=\"o\">/</span> <span class=\"mi\">100</span>\n\n    <span class=\"kd\">let</span> <span class=\"nv\">tipPercent</span><span class=\"p\">:</span> <span class=\"nb\">Double</span>\n    <span class=\"k\">switch</span> <span class=\"n\">tipPercentSegmentedControl</span><span class=\"p\">.</span><span class=\"n\">selectedSegmentIndex</span> <span class=\"p\">{</span>\n    <span class=\"k\">case</span> <span class=\"mi\">0</span><span class=\"p\">:</span>\n        <span class=\"n\">tipPercent</span> <span class=\"p\">=</span> <span class=\"mf\">0.15</span>\n    <span class=\"k\">case</span> <span class=\"mi\">1</span><span class=\"p\">:</span>\n        <span class=\"n\">tipPercent</span> <span class=\"p\">=</span> <span class=\"mf\">0.18</span>\n    <span class=\"k\">case</span> <span class=\"mi\">2</span><span class=\"p\">:</span>\n        <span class=\"n\">tipPercent</span> <span class=\"p\">=</span> <span class=\"mf\">0.20</span>\n    <span class=\"k\">default</span><span class=\"p\">:</span>\n        <span class=\"bp\">preconditionFailure</span><span class=\"p\">(</span><span class=\"s\">\"Unexpected index.\"</span><span class=\"p\">)</span>\n    <span class=\"p\">}</span>\n\n    <span class=\"kd\">let</span> <span class=\"nv\">tipAmount</span> <span class=\"p\">=</span> <span class=\"n\">roundedBillAmount</span> <span class=\"o\">*</span> <span class=\"n\">tipPercent</span>\n    <span class=\"kd\">let</span> <span class=\"nv\">roundedTipAmount</span> <span class=\"p\">=</span> <span class=\"p\">(</span><span class=\"mi\">100</span> <span class=\"o\">*</span> <span class=\"n\">tipAmount</span><span class=\"p\">).</span><span class=\"n\">rounded</span><span class=\"p\">()</span> <span class=\"o\">/</span> <span class=\"mi\">100</span>\n\n    <span class=\"kd\">let</span> <span class=\"nv\">totalAmount</span> <span class=\"p\">=</span> <span class=\"n\">roundedBillAmount</span> <span class=\"o\">+</span> <span class=\"n\">roundedTipAmount</span>\n\n    <span class=\"c1\">// Update UI</span>\n    <span class=\"kc\">self</span><span class=\"p\">.</span><span class=\"n\">billAmountTextField</span><span class=\"p\">.</span><span class=\"n\">text</span> <span class=\"p\">=</span> <span class=\"nb\">String</span><span class=\"p\">(</span><span class=\"n\">format</span><span class=\"p\">:</span> <span class=\"s\">\"%.2f\"</span><span class=\"p\">,</span> <span class=\"n\">roundedBillAmount</span><span class=\"p\">)</span>\n    <span class=\"kc\">self</span><span class=\"p\">.</span><span class=\"n\">tipAmountLabel</span><span class=\"p\">.</span><span class=\"n\">text</span> <span class=\"p\">=</span> <span class=\"nb\">String</span><span class=\"p\">(</span><span class=\"n\">format</span><span class=\"p\">:</span> <span class=\"s\">\"%.2f\"</span><span class=\"p\">,</span> <span class=\"n\">roundedTipAmount</span><span class=\"p\">)</span>\n    <span class=\"kc\">self</span><span class=\"p\">.</span><span class=\"n\">totalAmountLabel</span><span class=\"p\">.</span><span class=\"n\">text</span> <span class=\"p\">=</span> <span class=\"nb\">String</span><span class=\"p\">(</span><span class=\"n\">format</span><span class=\"p\">:</span> <span class=\"s\">\"%.2f\"</span><span class=\"p\">,</span> <span class=\"n\">totalAmount</span><span class=\"p\">)</span>\n<span class=\"p\">}</span>\n</pre>\n<p>In the code above, we use the <code>selectedSegmentIndex</code> of our segmented control with a <code>switch</code> statement to determine the correct tip percent. <code>tipPercent</code> is then used to correctly calculate our tip.</p>\n</div><p>Let's test out our new changes!</p><div class=\"action\">\n<p>\nBuild and run your project. Use different combinations of bill amounts and tip percents and see if the output card updates correctly.</p>\n</div>"},{"id":"T0E6OlNlY3Rpb24tMTI0","title":"Reset Button","htmlContent":"<p>To finish up our logic, let's implement our reset functionality.</p><p>Similar to our <code>calculate</code> logic, let's separate our reset logic into it's own function.</p><p>In our reset logic, we'll want to reset our tip calculator to it's initial state. We'll need to remember to do the following:</p><ul>\n<li>Set the text field's <code>text</code> value to <code>nil</code>\n</li>\n<li>Set the segmented control's <code>selectedSegmentIndex</code> to <code>0</code>\n</li>\n<li>Set both output labels on the output card back to <code>$0.00</code>\n</li>\n</ul><div class=\"challenge\">\n<p>\nTry implementing the logic above in a function called <code>clear()</code>.</p>\n</div><!-- break --><div class=\"solution\">\n<p>\nYour new <code>clear()</code> function should be the following:</p>\n<pre><span class=\"kd\">func</span> <span class=\"nf\">clear</span><span class=\"p\">()</span> <span class=\"p\">{</span>\n    <span class=\"n\">billAmountTextField</span><span class=\"p\">.</span><span class=\"n\">text</span> <span class=\"p\">=</span> <span class=\"kc\">nil</span>\n    <span class=\"n\">tipPercentSegmentedControl</span><span class=\"p\">.</span><span class=\"n\">selectedSegmentIndex</span> <span class=\"p\">=</span> <span class=\"mi\">0</span>\n    <span class=\"n\">tipAmountLabel</span><span class=\"p\">.</span><span class=\"n\">text</span> <span class=\"p\">=</span> <span class=\"s\">\"$0.00\"</span>\n    <span class=\"n\">totalAmountLabel</span><span class=\"p\">.</span><span class=\"n\">text</span> <span class=\"p\">=</span> <span class=\"s\">\"$0.00\"</span>\n<span class=\"p\">}</span>\n</pre>\n</div><p>Next, we'll need to update the <code>IBAction</code> of our reset button.</p><div class=\"action\">\n<p>\nIn <code>ViewController.swift</code>, update your <code>resetButtonTapped(_:)</code> method with the following:</p>\n<pre><span class=\"err\">@</span><span class=\"nx\">IBAction</span> <span class=\"nx\">func</span> <span class=\"nx\">resetButtonTapped</span><span class=\"p\">(</span><span class=\"nx\">_</span> <span class=\"nx\">sender</span><span class=\"o\">:</span> <span class=\"nx\">UIButton</span><span class=\"p\">)</span> <span class=\"p\">{</span>\n    <span class=\"nx\">clear</span><span class=\"p\">()</span>\n<span class=\"p\">}</span>\n</pre>\n</div><p>Last, when our <code>calculate</code> gets invalid input, let's also reset the calculator's state.</p><div class=\"action\">\n<p>\nChange <code>calculate()</code> to the following:</p>\n<pre><span class=\"kd\">func</span> <span class=\"nf\">calculate</span><span class=\"p\">()</span> <span class=\"p\">{</span>\n    <span class=\"c1\">// dismiss keyboard</span>\n    <span class=\"k\">if</span> <span class=\"kc\">self</span><span class=\"p\">.</span><span class=\"n\">billAmountTextField</span><span class=\"p\">.</span><span class=\"n\">isFirstResponder</span> <span class=\"p\">{</span>\n        <span class=\"kc\">self</span><span class=\"p\">.</span><span class=\"n\">billAmountTextField</span><span class=\"p\">.</span><span class=\"n\">resignFirstResponder</span><span class=\"p\">()</span>\n    <span class=\"p\">}</span>\n\n    <span class=\"k\">guard</span> <span class=\"kd\">let</span> <span class=\"nv\">billAmountText</span> <span class=\"p\">=</span> <span class=\"kc\">self</span><span class=\"p\">.</span><span class=\"n\">billAmountTextField</span><span class=\"p\">.</span><span class=\"n\">text</span><span class=\"p\">,</span>\n        <span class=\"kd\">let</span> <span class=\"nv\">billAmount</span> <span class=\"p\">=</span> <span class=\"nb\">Double</span><span class=\"p\">(</span><span class=\"n\">billAmountText</span><span class=\"p\">)</span> <span class=\"k\">else</span> <span class=\"p\">{</span>\n            <span class=\"n\">clear</span><span class=\"p\">()</span>\n            <span class=\"k\">return</span>\n    <span class=\"p\">}</span>\n\n    <span class=\"c1\">// ...</span>\n\n<span class=\"p\">}</span>\n</pre>\n</div>"},{"id":"T0E6OlNlY3Rpb24tMTI1","title":"Conclusion","htmlContent":"<p>It works! In this section, we've taken our UI and IB connections and implemented the logic behind our tip calculator.</p><p>We started by retrieving the user's input from the <em>Bill Amount Text Field</em>. Next, we used the user's input to calculate bill's tip and total amounts. To finish up, we updated our UI by setting each respective label on our <em>Output Card</em>.</p><p>In the next section, we'll finish the remaining styling and functionality of our tip calculator!</p>"}]},"next":{"id":"T0E6OlBhZ2UtNDE=","slug":"theming","title":"Theming and Styling"},"previous":{"id":"T0E6OlBhZ2UtNDE=","slug":"theming","title":"Theming and Styling"}},{"id":"T0E6OlBhZ2UtNDE=","title":"Theming and Styling","slug":"theming","sections":{"nodes":[{"id":"T0E6OlNlY3Rpb24tMTE5Mjg=","title":"Theming and Styling","htmlContent":"<p>To finish our tip calculator, we'll need to add some final touches to styling and implement our light/dark theme switch.</p><p>Let's review what our app looks like so far:</p><p><a href=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P6-Theming/assets/current_app.png\" target=\"_blank\">\n          <img src=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P6-Theming/assets/current_app.png\" alt=\"Current App\" title=\"\">\n        </a></p><p>Next, let's take a look at our designs:</p><p><a href=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P6-Theming/assets/final_design.png\" target=\"_blank\">\n          <img src=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P6-Theming/assets/final_design.png\" alt=\"Final Design\" title=\"\">\n        </a></p><p>Although the differences are subtle, to complete our UI, we'll need to add the following:</p><ul>\n<li>header view shadow</li>\n<li>input card rounded corners</li>\n<li>output card rounded corners</li>\n<li>reset button rounded corners</li>\n<li>output card border</li>\n</ul><p>Let's start by making these changes!</p>"},{"id":"T0E6OlNlY3Rpb24tMTE5Mjk=","title":"Configuring Layers","htmlContent":"<p>To make our final UI changes, we'll need to learn about <code>CALayer</code>.</p><p>Each <code>UIView</code> object has a <code>layer</code> property of type <code>CALayer</code>. The view's layer is a lower-level API that gives developers more control on how the view is rendered.</p><p>By using each view's <code>layer</code> property, we can easily create shadows, add rounded corners and display borders.</p><p>Before we start with configuring our view's layers, let's first create a new, empty method in our view controller.</p><div class=\"action\">\n<p>\nIn <code>ViewController.swift</code>, add the following function:</p>\n<pre><span class=\"kd\">func</span> <span class=\"nf\">setupViews</span><span class=\"p\">()</span> <span class=\"p\">{</span>\n    <span class=\"c1\">// nothing yet</span>\n<span class=\"p\">}</span>\n</pre>\n</div><p>We'll use this method to add code that initially configures each view's respective layer.</p><p>This function will need to be called at the beginning of the view controller's lifecycle so it initially makes all of our layer customizations.</p><div class=\"action\">\n<p>\nIn <code>ViewController.swift</code>, call <code>setupViews()</code> in <code>viewDidLoad()</code>:</p>\n<pre><span class=\"kr\">override</span> <span class=\"kd\">func</span> <span class=\"nf\">viewDidLoad</span><span class=\"p\">()</span> <span class=\"p\">{</span>\n    <span class=\"kc\">super</span><span class=\"p\">.</span><span class=\"n\">viewDidLoad</span><span class=\"p\">()</span>\n\n    <span class=\"n\">setupViews</span><span class=\"p\">()</span>\n\n    <span class=\"n\">billAmountTextField</span><span class=\"p\">.</span><span class=\"n\">calculateButtonAction</span> <span class=\"p\">=</span> <span class=\"p\">{</span>\n        <span class=\"kc\">self</span><span class=\"p\">.</span><span class=\"n\">calculate</span><span class=\"p\">()</span>\n    <span class=\"p\">}</span>\n<span class=\"p\">}</span>\n</pre>\n</div><p>With our near <code>setupViews()</code> method, we can add the code for adding a shadow to the bottom of the header view.</p><div class=\"action\">\n<p>\nAdd a shadow by configuring the <em>Header View's</em> layer:</p>\n<pre><span class=\"kd\">func</span> <span class=\"nf\">setupViews</span><span class=\"p\">()</span> <span class=\"p\">{</span>\n    <span class=\"n\">headerView</span><span class=\"p\">.</span><span class=\"n\">layer</span><span class=\"p\">.</span><span class=\"n\">shadowOffset</span> <span class=\"p\">=</span> <span class=\"bp\">CGSize</span><span class=\"p\">(</span><span class=\"n\">width</span><span class=\"p\">:</span> <span class=\"mi\">0</span><span class=\"p\">,</span> <span class=\"n\">height</span><span class=\"p\">:</span> <span class=\"mi\">1</span><span class=\"p\">)</span>\n    <span class=\"n\">headerView</span><span class=\"p\">.</span><span class=\"n\">layer</span><span class=\"p\">.</span><span class=\"n\">shadowOpacity</span> <span class=\"p\">=</span> <span class=\"mf\">0.05</span>\n    <span class=\"n\">headerView</span><span class=\"p\">.</span><span class=\"n\">layer</span><span class=\"p\">.</span><span class=\"n\">shadowColor</span> <span class=\"p\">=</span> <span class=\"bp\">UIColor</span><span class=\"p\">.</span><span class=\"n\">black</span><span class=\"p\">.</span><span class=\"n\">cgColor</span>\n    <span class=\"n\">headerView</span><span class=\"p\">.</span><span class=\"n\">layer</span><span class=\"p\">.</span><span class=\"n\">shadowRadius</span> <span class=\"p\">=</span> <span class=\"mi\">35</span>\n<span class=\"p\">}</span>\n</pre>\n<p><code>CALayer</code> has many attributes that allow you to configure a view's appearance. In the code above, we add code to create a slight shadow for our <em>Header View</em>.</p>\n\n<p>Build and run your project. You should see your shadow appear under your <em>Header View</em>:</p>\n\n<p><a href=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P6-Theming/assets/header_shadow.png\" target=\"_blank\">\n          <img src=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P6-Theming/assets/header_shadow.png\" alt=\"Header Shadow\" title=\"\">\n        </a></p>\n</div><!-- break --><div class=\"info\">\n<p>\nThe shadow in our UI is soft and can be hard to see. If you want to test that your code works, you can adjust the layer's <code>shadowOpacity</code> to a value closer to <code>1</code>. Don't forget to change the value back after testing.</p>\n</div><p>Next, we'll look at setting a view's layer to have rounded corners.</p><h2>Rounded Corners</h2><p>Similar to setting our shadow, each <code>CALayer</code> also has a <code>cornerRadius</code> property that we can adjust to give our view a rounded corner.</p><p>Let's add the code to give our <em>Input Card</em> rounded corners.</p><div class=\"action\">\n<p>\nAdd rounded corners to the input card:</p>\n<pre><span class=\"kd\">func</span> <span class=\"nf\">setupViews</span><span class=\"p\">()</span> <span class=\"p\">{</span>\n    <span class=\"n\">headerView</span><span class=\"p\">.</span><span class=\"n\">layer</span><span class=\"p\">.</span><span class=\"n\">shadowOffset</span> <span class=\"p\">=</span> <span class=\"bp\">CGSize</span><span class=\"p\">(</span><span class=\"n\">width</span><span class=\"p\">:</span> <span class=\"mi\">0</span><span class=\"p\">,</span> <span class=\"n\">height</span><span class=\"p\">:</span> <span class=\"mi\">1</span><span class=\"p\">)</span>\n    <span class=\"n\">headerView</span><span class=\"p\">.</span><span class=\"n\">layer</span><span class=\"p\">.</span><span class=\"n\">shadowOpacity</span> <span class=\"p\">=</span> <span class=\"mf\">0.05</span>\n    <span class=\"n\">headerView</span><span class=\"p\">.</span><span class=\"n\">layer</span><span class=\"p\">.</span><span class=\"n\">shadowColor</span> <span class=\"p\">=</span> <span class=\"bp\">UIColor</span><span class=\"p\">.</span><span class=\"n\">black</span><span class=\"p\">.</span><span class=\"n\">cgColor</span>\n    <span class=\"n\">headerView</span><span class=\"p\">.</span><span class=\"n\">layer</span><span class=\"p\">.</span><span class=\"n\">shadowRadius</span> <span class=\"p\">=</span> <span class=\"mi\">35</span>\n\n    <span class=\"n\">inputCardView</span><span class=\"p\">.</span><span class=\"n\">layer</span><span class=\"p\">.</span><span class=\"n\">cornerRadius</span> <span class=\"p\">=</span> <span class=\"mi\">8</span>\n    <span class=\"n\">inputCardView</span><span class=\"p\">.</span><span class=\"n\">layer</span><span class=\"p\">.</span><span class=\"n\">masksToBounds</span> <span class=\"p\">=</span> <span class=\"kc\">true</span>\n<span class=\"p\">}</span>\n</pre>\n<p>It's important to note that we also set the layer's <code>maskToBounds</code> property to <code>true</code>. This prevents our view's content from appearing outside of our rounded corner's boundary.</p>\n</div><p>Let's test that our code works!</p><div class=\"action\">\n<p>\nBuild and run your project the updates to your UI:</p>\n\n<p><a href=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P6-Theming/assets/input_rounded_corners.png\" target=\"_blank\">\n          <img src=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P6-Theming/assets/input_rounded_corners.png\" alt=\"Input Rounded Corners\" title=\"\">\n        </a></p>\n</div><p>Easy enough! Time to practice on your own.</p><div class=\"challenge\">\n<p>\nAdd rounded corners (with the same corner radius as above) to give both the <code>outputCardView</code> and <code>resetButton</code> rounded corners.</p>\n</div><!-- break --><div class=\"solution\">\n<p>\nTo add rounded corners for both views, you should have added the code below to your <code>setupViews()</code> method:</p>\n<pre><span class=\"kd\">func</span> <span class=\"nf\">setupViews</span><span class=\"p\">()</span> <span class=\"p\">{</span>\n\n    <span class=\"c1\">// ...</span>\n\n    <span class=\"n\">outputCardView</span><span class=\"p\">.</span><span class=\"n\">layer</span><span class=\"p\">.</span><span class=\"n\">cornerRadius</span> <span class=\"p\">=</span> <span class=\"mi\">8</span>\n    <span class=\"n\">outputCardView</span><span class=\"p\">.</span><span class=\"n\">layer</span><span class=\"p\">.</span><span class=\"n\">masksToBounds</span> <span class=\"p\">=</span> <span class=\"kc\">true</span>\n\n    <span class=\"n\">resetButton</span><span class=\"p\">.</span><span class=\"n\">layer</span><span class=\"p\">.</span><span class=\"n\">cornerRadius</span> <span class=\"p\">=</span> <span class=\"mi\">8</span>\n    <span class=\"n\">resetButton</span><span class=\"p\">.</span><span class=\"n\">layer</span><span class=\"p\">.</span><span class=\"n\">masksToBounds</span> <span class=\"p\">=</span> <span class=\"kc\">true</span>\n<span class=\"p\">}</span>\n</pre>\n</div><h2>Borders</h2><p>To finish up our UI changes, we'll need to add a border to our output card. Again, <code>CALayer</code> has two properties: <code>borderWidth</code> and <code>borderColor</code> that allow us to set a border for a layer. No surprise...</p><div class=\"action\">\n<p>\nAdd the following code to <code>setupViews()</code>:</p>\n<pre><span class=\"kd\">func</span> <span class=\"nf\">setupViews</span><span class=\"p\">()</span> <span class=\"p\">{</span>\n\n    <span class=\"c1\">// ...</span>\n\n    <span class=\"n\">outputCardView</span><span class=\"p\">.</span><span class=\"n\">layer</span><span class=\"p\">.</span><span class=\"n\">cornerRadius</span> <span class=\"p\">=</span> <span class=\"mi\">8</span>\n    <span class=\"n\">outputCardView</span><span class=\"p\">.</span><span class=\"n\">layer</span><span class=\"p\">.</span><span class=\"n\">masksToBounds</span> <span class=\"p\">=</span> <span class=\"kc\">true</span>\n\n    <span class=\"c1\">// set output card border</span>\n    <span class=\"n\">outputCardView</span><span class=\"p\">.</span><span class=\"n\">layer</span><span class=\"p\">.</span><span class=\"n\">borderWidth</span> <span class=\"p\">=</span> <span class=\"mi\">1</span>\n    <span class=\"n\">outputCardView</span><span class=\"p\">.</span><span class=\"n\">layer</span><span class=\"p\">.</span><span class=\"n\">borderColor</span> <span class=\"p\">=</span> <span class=\"bp\">UIColor</span><span class=\"p\">.</span><span class=\"n\">tcHotPink</span><span class=\"p\">.</span><span class=\"n\">cgColor</span>\n\n    <span class=\"n\">resetButton</span><span class=\"p\">.</span><span class=\"n\">layer</span><span class=\"p\">.</span><span class=\"n\">cornerRadius</span> <span class=\"p\">=</span> <span class=\"mi\">8</span>\n    <span class=\"n\">resetButton</span><span class=\"p\">.</span><span class=\"n\">layer</span><span class=\"p\">.</span><span class=\"n\">masksToBounds</span> <span class=\"p\">=</span> <span class=\"kc\">true</span>\n<span class=\"p\">}</span>\n</pre>\n</div><p>We've finished styling our tip calculator's subviews. Your tip calculator should look like the following:</p><p><a href=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P6-Theming/assets/finished_ui.png\" target=\"_blank\">\n          <img src=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P6-Theming/assets/finished_ui.png\" alt=\"Finished UI\" title=\"\">\n        </a></p>"},{"id":"T0E6OlNlY3Rpb24tMTE5MzA=","title":"Light / Dark Theme","htmlContent":"<p>The last feature we need to implement is the ability to toggle themes. Currently, our app has a light colored theme. When we're finished, our <code>UISwitch</code> will be able to toggle from our light colored theme to a dark one (and vice versa).</p><p>Let's start by creating a new function that will eventually contain all our theme switching code.</p><div class=\"action\">\n<p>\nIn <code>ViewController.swift</code>, add the following new method:</p>\n<pre><span class=\"kd\">func</span> <span class=\"nf\">setTheme</span><span class=\"p\">(</span><span class=\"n\">isDark</span><span class=\"p\">:</span> <span class=\"nb\">Bool</span><span class=\"p\">)</span> <span class=\"p\">{</span>\n\n<span class=\"p\">}</span>\n</pre>\n</div><p>Next, we'll create a new data structure that contains each theme's color information. When we're done, we'll be able to use this object to switch between themes.</p><div class=\"action\">\n<p>\nCreate a new <code>ColorTheme</code> struct:</p>\n\n<ol>\n<li>Press CMD-N to create a new file into your project. <a href=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P6-Theming/assets/new_file_template.png\" target=\"_blank\">\n          <img src=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P6-Theming/assets/new_file_template.png\" alt=\"New File Template\" title=\"\">\n        </a>\n</li>\n<li>Select <em>Swift File</em> and click <em>Next</em> . <a href=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P6-Theming/assets/select_swift_template.png\" target=\"_blank\">\n          <img src=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P6-Theming/assets/select_swift_template.png\" alt=\"Select Swift Template\" title=\"\">\n        </a>\n</li>\n<li>Name your new Swift file <code>ColorTheme.swift</code> and click <em>Create</em>. <a href=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P6-Theming/assets/set_struct_name.png\" target=\"_blank\">\n          <img src=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P6-Theming/assets/set_struct_name.png\" alt=\"Set Struct Name\" title=\"\">\n        </a>\n</li>\n</ol>\n\n<p>When you're finished, you should see a new Swift source file named <code>ColorTheme.swift</code>:</p>\n\n<p><a href=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P6-Theming/assets/new_empty_file.png\" target=\"_blank\">\n          <img src=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P6-Theming/assets/new_empty_file.png\" alt=\"New Empty File\" title=\"\">\n        </a></p>\n</div><p>With our new source file, we can create our <code>ColorTheme</code> data structure.</p><div class=\"action\">\n<p>\nIn <code>ColorTheme.swift</code>, add the following code:</p>\n<pre><span class=\"kd\">import</span> <span class=\"nc\">UIKit</span>\n\n<span class=\"kd\">struct</span> <span class=\"nc\">ColorTheme</span> <span class=\"p\">{</span>\n\n    <span class=\"c1\">// </span><span class=\"cs\">MARK:</span><span class=\"c1\"> - Instance Vars</span>\n\n    <span class=\"kd\">let</span> <span class=\"nv\">isDefaultStatusBar</span><span class=\"p\">:</span> <span class=\"nb\">Bool</span>\n    <span class=\"kd\">let</span> <span class=\"nv\">viewControllerBackgroundColor</span><span class=\"p\">:</span> <span class=\"bp\">UIColor</span>\n\n    <span class=\"kd\">let</span> <span class=\"nv\">primaryColor</span><span class=\"p\">:</span> <span class=\"bp\">UIColor</span>\n    <span class=\"kd\">let</span> <span class=\"nv\">primaryTextColor</span><span class=\"p\">:</span> <span class=\"bp\">UIColor</span>\n\n    <span class=\"kd\">let</span> <span class=\"nv\">secondaryColor</span><span class=\"p\">:</span> <span class=\"bp\">UIColor</span>\n\n    <span class=\"kd\">let</span> <span class=\"nv\">accentColor</span><span class=\"p\">:</span> <span class=\"bp\">UIColor</span>\n    <span class=\"kd\">let</span> <span class=\"nv\">outputTextColor</span><span class=\"p\">:</span> <span class=\"bp\">UIColor</span>\n<span class=\"p\">}</span>\n</pre>\n<p>We create a new <code>struct</code> that contains the data for each theme. Each property in <code>ColorTheme</code> sets the color of a corresponding view in our tip calculator's UI.</p>\n</div><p>Using our <code>ColorTheme</code> struct, we can create our light and dark color themes. We'll do this using class variables.</p><div class=\"action\">\n<p>\nIn <code>ColorTheme.swift</code>, create two new class variables:</p>\n<pre><span class=\"nx\">struct</span> <span class=\"nx\">ColorTheme</span> <span class=\"p\">{</span>\n\n    <span class=\"c1\">// MARK: - Class Vars</span>\n\n    <span class=\"kr\">static</span> <span class=\"kd\">let</span> <span class=\"nx\">light</span> <span class=\"o\">=</span> <span class=\"nx\">ColorTheme</span><span class=\"p\">(</span><span class=\"nx\">isDefaultStatusBar</span><span class=\"o\">:</span> <span class=\"kc\">true</span><span class=\"p\">,</span>\n                                  <span class=\"nx\">viewControllerBackgroundColor</span><span class=\"o\">:</span> <span class=\"p\">.</span><span class=\"nx\">tcOffWhite</span><span class=\"p\">,</span>\n                                  <span class=\"nx\">primaryColor</span><span class=\"o\">:</span> <span class=\"p\">.</span><span class=\"nx\">tcWhite</span><span class=\"p\">,</span>\n                                  <span class=\"nx\">primaryTextColor</span><span class=\"o\">:</span> <span class=\"p\">.</span><span class=\"nx\">tcCharcoal</span><span class=\"p\">,</span>\n                                  <span class=\"nx\">secondaryColor</span><span class=\"o\">:</span> <span class=\"p\">.</span><span class=\"nx\">tcDarkBlue</span><span class=\"p\">,</span>\n                                  <span class=\"nx\">accentColor</span><span class=\"o\">:</span> <span class=\"p\">.</span><span class=\"nx\">tcHotPink</span><span class=\"p\">,</span>\n                                  <span class=\"nx\">outputTextColor</span><span class=\"o\">:</span> <span class=\"p\">.</span><span class=\"nx\">tcAlmostBlack</span><span class=\"p\">)</span>\n\n    <span class=\"kr\">static</span> <span class=\"kd\">let</span> <span class=\"nx\">dark</span> <span class=\"o\">=</span> <span class=\"nx\">ColorTheme</span><span class=\"p\">(</span><span class=\"nx\">isDefaultStatusBar</span><span class=\"o\">:</span> <span class=\"kc\">false</span><span class=\"p\">,</span>\n                                 <span class=\"nx\">viewControllerBackgroundColor</span><span class=\"o\">:</span> <span class=\"p\">.</span><span class=\"nx\">tcAlmostBlack</span><span class=\"p\">,</span>\n                                 <span class=\"nx\">primaryColor</span><span class=\"o\">:</span> <span class=\"p\">.</span><span class=\"nx\">tcMediumBlack</span><span class=\"p\">,</span>\n                                 <span class=\"nx\">primaryTextColor</span><span class=\"o\">:</span> <span class=\"p\">.</span><span class=\"nx\">tcWhite</span><span class=\"p\">,</span>\n                                 <span class=\"nx\">secondaryColor</span><span class=\"o\">:</span> <span class=\"p\">.</span><span class=\"nx\">tcBlueBlack</span><span class=\"p\">,</span>\n                                 <span class=\"nx\">accentColor</span><span class=\"o\">:</span> <span class=\"p\">.</span><span class=\"nx\">tcSeafoamGreen</span><span class=\"p\">,</span>\n                                 <span class=\"nx\">outputTextColor</span><span class=\"o\">:</span> <span class=\"p\">.</span><span class=\"nx\">tcWhite</span><span class=\"p\">)</span>\n\n    <span class=\"c1\">// ...</span>\n\n<span class=\"p\">}</span>\n</pre>\n</div><p>We can use the data from the class variables we created to change the current color theme of our tip calculator.</p><div class=\"action\">\n<p>\nIn <code>ViewController.swift</code>, update <code>setTheme(isDark:)</code> to use our change the color of our tip calculator depending on the active theme.</p>\n<pre><span class=\"kd\">func</span> <span class=\"nf\">setTheme</span><span class=\"p\">(</span><span class=\"n\">isDark</span><span class=\"p\">:</span> <span class=\"nb\">Bool</span><span class=\"p\">)</span> <span class=\"p\">{</span>\n    <span class=\"kd\">let</span> <span class=\"nv\">theme</span> <span class=\"p\">=</span> <span class=\"n\">isDark</span> <span class=\"p\">?</span> <span class=\"n\">ColorTheme</span><span class=\"p\">.</span><span class=\"n\">dark</span> <span class=\"p\">:</span> <span class=\"n\">ColorTheme</span><span class=\"p\">.</span><span class=\"n\">light</span>\n\n    <span class=\"n\">view</span><span class=\"p\">.</span><span class=\"n\">backgroundColor</span> <span class=\"p\">=</span> <span class=\"n\">theme</span><span class=\"p\">.</span><span class=\"n\">viewControllerBackgroundColor</span>\n\n    <span class=\"n\">headerView</span><span class=\"p\">.</span><span class=\"n\">backgroundColor</span> <span class=\"p\">=</span> <span class=\"n\">theme</span><span class=\"p\">.</span><span class=\"n\">primaryColor</span>\n    <span class=\"n\">titleLabel</span><span class=\"p\">.</span><span class=\"n\">textColor</span> <span class=\"p\">=</span> <span class=\"n\">theme</span><span class=\"p\">.</span><span class=\"n\">primaryTextColor</span>\n\n    <span class=\"n\">inputCardView</span><span class=\"p\">.</span><span class=\"n\">backgroundColor</span> <span class=\"p\">=</span> <span class=\"n\">theme</span><span class=\"p\">.</span><span class=\"n\">secondaryColor</span>\n\n    <span class=\"n\">billAmountTextField</span><span class=\"p\">.</span><span class=\"n\">tintColor</span> <span class=\"p\">=</span> <span class=\"n\">theme</span><span class=\"p\">.</span><span class=\"n\">accentColor</span>\n    <span class=\"n\">tipPercentSegmentedControl</span><span class=\"p\">.</span><span class=\"n\">tintColor</span> <span class=\"p\">=</span> <span class=\"n\">theme</span><span class=\"p\">.</span><span class=\"n\">accentColor</span>\n\n    <span class=\"n\">outputCardView</span><span class=\"p\">.</span><span class=\"n\">backgroundColor</span> <span class=\"p\">=</span> <span class=\"n\">theme</span><span class=\"p\">.</span><span class=\"n\">primaryColor</span>\n    <span class=\"n\">outputCardView</span><span class=\"p\">.</span><span class=\"n\">layer</span><span class=\"p\">.</span><span class=\"n\">borderColor</span> <span class=\"p\">=</span> <span class=\"n\">theme</span><span class=\"p\">.</span><span class=\"n\">accentColor</span><span class=\"p\">.</span><span class=\"n\">cgColor</span>\n\n    <span class=\"n\">tipAmountTitleLabel</span><span class=\"p\">.</span><span class=\"n\">textColor</span> <span class=\"p\">=</span> <span class=\"n\">theme</span><span class=\"p\">.</span><span class=\"n\">primaryTextColor</span>\n    <span class=\"n\">totalAmountTitleLabel</span><span class=\"p\">.</span><span class=\"n\">textColor</span> <span class=\"p\">=</span> <span class=\"n\">theme</span><span class=\"p\">.</span><span class=\"n\">primaryTextColor</span>\n\n    <span class=\"n\">tipAmountLabel</span><span class=\"p\">.</span><span class=\"n\">textColor</span> <span class=\"p\">=</span> <span class=\"n\">theme</span><span class=\"p\">.</span><span class=\"n\">outputTextColor</span>\n    <span class=\"n\">totalAmountLabel</span><span class=\"p\">.</span><span class=\"n\">textColor</span> <span class=\"p\">=</span> <span class=\"n\">theme</span><span class=\"p\">.</span><span class=\"n\">outputTextColor</span>\n\n    <span class=\"n\">resetButton</span><span class=\"p\">.</span><span class=\"n\">backgroundColor</span> <span class=\"p\">=</span> <span class=\"n\">theme</span><span class=\"p\">.</span><span class=\"n\">secondaryColor</span>\n<span class=\"p\">}</span>\n</pre>\n</div><p>In addition, we'll need to add some more code to make sure the color of our status bar is correctly updated.</p><div class=\"action\">\n<p>\nIn <code>ViewController.swift</code>, add the following properties to the top of your class:</p>\n<pre><span class=\"kd\">class</span> <span class=\"nc\">ViewController</span><span class=\"p\">:</span> <span class=\"bp\">UIViewController</span> <span class=\"p\">{</span>\n\n    <span class=\"c1\">// </span><span class=\"cs\">MARK:</span><span class=\"c1\"> - Properties</span>\n\n    <span class=\"c1\">// 1</span>\n    <span class=\"kd\">var</span> <span class=\"nv\">isDefaultStatusBar</span> <span class=\"p\">=</span> <span class=\"kc\">true</span>\n\n    <span class=\"c1\">// 2</span>\n    <span class=\"kr\">override</span> <span class=\"kd\">var</span> <span class=\"nv\">preferredStatusBarStyle</span><span class=\"p\">:</span> <span class=\"n\">UIStatusBarStyle</span> <span class=\"p\">{</span>\n        <span class=\"k\">return</span> <span class=\"n\">isDefaultStatusBar</span> <span class=\"p\">?</span> <span class=\"p\">.</span><span class=\"k\">default</span> <span class=\"p\">:</span> <span class=\"p\">.</span><span class=\"n\">lightContent</span>\n    <span class=\"p\">}</span>\n\n    <span class=\"c1\">// ...</span>\n\n<span class=\"p\">}</span>\n</pre>\n<p>Explaining the new properties we added:</p>\n\n<ol>\n<li>\n<code>isDefaultStatusBar</code> keeps our <code>Bool</code> of whether we should show the default or light status bar. If default, the status bar color is black.</li>\n<li>We override the <code>preferredStatusBarStyle</code> property and use <code>isDefaultStatusBar</code> to set our view controller's status bar style.</li>\n</ol>\n\n<p>You might be wondering 'Why we need two properties to set the status bar style?'. Good question. Our <code>preferredStatusBarStyle</code> property is inherited from our super class and can't be set directly. Because of this, we need our <code>isDefaultStatusBar</code> variable to keep track of which status bar style <code>preferredStatusBarStyle</code> should display.</p>\n</div><!-- break --><p>To make sure our status bar is updated when our theme is toggled, we'll need to add the following code to our <code>setTheme(isDark:)</code> method.</p><div class=\"action\">\n<p>\nIn <code>ViewController.swift</code>, update <code>setTheme(isDark:)</code>:</p>\n<pre><span class=\"kd\">func</span> <span class=\"nf\">setTheme</span><span class=\"p\">(</span><span class=\"n\">isDark</span><span class=\"p\">:</span> <span class=\"nb\">Bool</span><span class=\"p\">)</span> <span class=\"p\">{</span>\n\n    <span class=\"c1\">// ...</span>\n\n    <span class=\"n\">isDefaultStatusBar</span> <span class=\"p\">=</span> <span class=\"n\">theme</span><span class=\"p\">.</span><span class=\"n\">isDefaultStatusBar</span>\n    <span class=\"n\">setNeedsStatusBarAppearanceUpdate</span><span class=\"p\">()</span>\n<span class=\"p\">}</span>\n</pre>\n</div><h2>Implementing Our IBAction</h2><p>To toggle our theme each time our <code>UISwitch</code> is toggled, we'll need to connect our <code>setTheme(isDark:)</code> to our <code>themeToggled(_:)</code> method.</p><div class=\"action\">\n<p>\nCall <code>setTheme(isDark:)</code> in <code>themeToggled(_:)</code>:</p>\n<pre><span class=\"nd\">@IBAction</span> <span class=\"n\">func</span> <span class=\"n\">themeToggled</span><span class=\"p\">(</span><span class=\"n\">_</span> <span class=\"n\">sender</span><span class=\"p\">:</span> <span class=\"n\">UISwitch</span><span class=\"p\">)</span> <span class=\"p\">{</span>\n    <span class=\"n\">setTheme</span><span class=\"p\">(</span><span class=\"n\">isDark</span><span class=\"p\">:</span> <span class=\"n\">sender</span><span class=\"o\">.</span><span class=\"n\">isOn</span><span class=\"p\">)</span>\n<span class=\"p\">}</span>\n</pre>\n<p>Our theme will be switched from light to dark and vice versa each time our <code>UISwitch</code> is toggled. The theme will be set corresponding to the switch's <code>isOn</code> property.</p>\n</div><h2>Initial Theme Setup</h2><p>To clean up, we'll need to make sure to set the initial theme state for our tip calculator. We can do this by calling our <code>setTheme(isDark:)</code> at the beginning of our view controller lifecycle.</p><div class=\"action\">\n<p>\nIn <code>ViewController.swift</code>, change your view controller to the following:</p>\n<pre><span class=\"kr\">override</span> <span class=\"kd\">func</span> <span class=\"nf\">viewDidLoad</span><span class=\"p\">()</span> <span class=\"p\">{</span>\n    <span class=\"kc\">super</span><span class=\"p\">.</span><span class=\"n\">viewDidLoad</span><span class=\"p\">()</span>\n\n    <span class=\"n\">setupViews</span><span class=\"p\">()</span>\n    <span class=\"n\">setTheme</span><span class=\"p\">(</span><span class=\"n\">isDark</span><span class=\"p\">:</span> <span class=\"kc\">false</span><span class=\"p\">)</span>\n\n    <span class=\"n\">billAmountTextField</span><span class=\"p\">.</span><span class=\"n\">calculateButtonAction</span> <span class=\"p\">=</span> <span class=\"p\">{</span>\n        <span class=\"kc\">self</span><span class=\"p\">.</span><span class=\"n\">calculate</span><span class=\"p\">()</span>\n    <span class=\"p\">}</span>\n<span class=\"p\">}</span>\n</pre>\n<p>We call <code>setTheme(isDark: false)</code> so that when our view controller's view are first setup, our initial theme will be set.</p>\n</div><p>Let's test our code to see if it works!</p><div class=\"action\">\n<p>\nBuild and run your project. Toggle the <code>UISwitch</code> to switch between light and dark color themes. If everything goes well, you should be able to use your tip calculator in dark mode! Which theme do you like better?</p>\n\n<p><a href=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P6-Theming/assets/finished_ui_dark.png\" target=\"_blank\">\n          <img src=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P6-Theming/assets/finished_ui_dark.png\" alt=\"Finished UI Dark\" title=\"\">\n        </a></p>\n</div>"},{"id":"T0E6OlNlY3Rpb24tMTE5MzE=","title":"Feedback and Review - 2 minutes","htmlContent":"<p><strong>We promise this won't take longer than 2 minutes!</strong></p><p>Please take a moment to rate your understanding of the learning outcomes from this tutorial, and how we can improve it via our <a href=\"https://forms.gle/nbiTz8z1wWZgrwDSA\" target=\"_blank\">tutorial feedback form</a></p><p>This allows us to get feedback on how well the students are grasping the learning outcomes, and tells us where we can improve the tutorial experience.</p>"},{"id":"T0E6OlNlY3Rpb24tMTE5MzI=","title":"What's Next?","htmlContent":"<p>After implementing our theming feature, we've completed our tip calculator's functionality and design! In the next section, we'll review what we've learned and set you on a challenge to practice your new skills.</p>"}]},"next":{"id":"T0E6OlBhZ2UtNDI=","slug":"conclusion-oHM=","title":"Conclusion"},"previous":{"id":"T0E6OlBhZ2UtNDI=","slug":"conclusion-oHM=","title":"Conclusion"}},{"id":"T0E6OlBhZ2UtNDI=","title":"Conclusion","slug":"conclusion-oHM=","sections":{"nodes":[{"id":"T0E6OlNlY3Rpb24tMTI5","title":"Conclusion","htmlContent":"<p>Well done! You've finished your second iOS tutorial.</p><p><a href=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P7-Conclusion/assets/finished_app.png\" target=\"_blank\">\n          <img src=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P7-Conclusion/assets/finished_app.png\" alt=\"Finished App\" title=\"\">\n        </a></p><p>Along the way, you've picked up some new skills:</p><ul>\n<li>how to visually breakdown designs into views</li>\n<li>how to identify and use view components in UIKit</li>\n<li>how to create UI layouts with auto-layout, constraints and stack views</li>\n<li>how to programmatically get and set class properties</li>\n</ul><p>We've also got to review the basics:</p><ul>\n<li>navigating Xcode files using the <em>Project Navigator</em>\n</li>\n<li>using the <em>Assistant Editor</em> to display files side-by-side</li>\n<li>creating <code>IBOutlet</code> and <code>IBAction</code> connections with <em>Interface Builder</em>\n</li>\n</ul><p>Another app built. You're well on your way to becoming an awesome iOS developer.</p><p>Stop and take a moment to appreciate how far you've come!</p>"},{"id":"T0E6OlNlY3Rpb24tMTMw","title":"A Challenge Approaches","htmlContent":"<p>You're not done yet. After you finish soaking in the feel-good emotions, it's time to put your skills to the test.</p><h2>The Challenge</h2><p>If you're from another country, or just an avid traveller, you'll know that many countries don't have a custom of tipping. In these countries, our tip calculator won't do us much good.</p><p>So instead, you're going to build a <em>Currency Exchange Calculator</em> that you can use when you're traveling abroad. To build our <em>Currency Exchange Calculator</em> app, we'll use make of the same skills and concepts we learned during this tutorial.</p><p>As always, try completing this challenge as much on your own as possible. If you do get stuck, you can always refer back to this tutorial for help!</p><h2>App Design</h2><p><a href=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P7-Conclusion/assets/currency_xc_design.png\" target=\"_blank\">\n          <img src=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P7-Conclusion/assets/currency_xc_design.png\" alt=\"Currency Exchange Design\" title=\"\">\n        </a></p><p>Above is an example design you can use to build your <em>Currency Exchange Calculator</em>. It's based off a <a href=\"https://itunes.apple.com/us/app/currency-converter/id628148586?mt=8\" target=\"_blank\">popular currency convertor</a> on the App Store. Feel free to get creative and add your own style into the app design.</p><h2>Specs</h2><p>Just like your <em>Tip Calculator</em>, your <em>Currency Exchange Calculator</em> app will involve reading user input and converting it to a different value.</p><p>Your app should take a input of U.S. dollars and immediately convert it into a currency of your choice. Some popular currencies you can consider using include the following: Euro, Yen, Rupee, Bitcoin.</p><p>Notice that there aren't any text fields or segmented controllers in the design above. Each number is a button that should change the input and output of the currency convertor.</p><p>If you'd like a better idea of how the app works, go ahead and download the free version of this <a href=\"https://itunes.apple.com/us/app/currency-converter/id628148586?mt=8\" target=\"_blank\">popular currency convertor</a> on the App Store. You should <strong>not</strong> need to purchase anything to download this app.</p><div class=\"info\">\n<p>\nFor your exchange calculation, find the currency conversion rate online and hard-code it into your app.</p>\n</div><p>Good luck the challenge! Remember, you can look back on the tutorial or your previous code if you get stuck.</p>"}]},"next":null,"previous":null}]}},"page":{"id":"T0E6OlBhZ2UtMzg=","title":"UI Layout","slug":"ui-layout","sections":{"nodes":[{"id":"T0E6OlNlY3Rpb24tMTA1","title":"UI Layout","htmlContent":"<p>We'll start building our app by implementing the UI in <em>Interface Builder</em>. For reference, here are the tip calculator designs:</p><p><a href=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P3-UI-Layout/assets/tc_view_breakdown.png\" target=\"_blank\">\n          <img src=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P3-UI-Layout/assets/tc_view_breakdown.png\" alt=\"Design Breakdown\" title=\"\">\n        </a></p>"},{"id":"T0E6OlNlY3Rpb24tMTA2","title":"Creating Views","htmlContent":"<p>We'll get started by creating our header view with a <code>UIView</code>.</p><div class=\"info\">\n<p>\n<code>UIKit</code> has it's own header-like bar called the <code>UINavigationBar</code>. To keep things simple, we'll start from scratch and create our own header view instead of using iOS's <code>UINavigationBar</code>.</p>\n</div><!-- break --><div class=\"action\">\n<p>\nOpen <code>Main.storyboard</code> from your project navigator. You should see your single view controller. <a href=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P3-UI-Layout/assets/starting_storyboard.png\" target=\"_blank\">\n          <img src=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P3-UI-Layout/assets/starting_storyboard.png\" alt=\"Starting Storyboard\" title=\"\">\n        </a></p>\n</div><p>Next, we'll add a <code>UIView</code> and reposition/resize it to be our header view.</p><div class=\"action\">\n<p>\nCreate a header view by dragging an <code>UIView</code> object from the <em>Object Library</em> to the top of the view controller. Don't worry too much about the perfect size and position for now. We'll handle that later.</p>\n\n<p><video width=\"100%\" controls><source src=\"https://s3.amazonaws.com/mgwu-misc/Tip+Calculator+Swift+4/p3_ui_layout/add_custom_nav_bar.mp4\" type=\"video/mp4\"></source></video></p>\n</div><p>The new <code>UIView</code> object that we just added is going to be our custom header view. We'll add other subviews onto it later.</p><p>You might notice, that our header view is a little hard to see because it's the same color as the view controller's root view: white. Let's change the color of our root view to add some contrast.</p><div class=\"action\">\n<p>\nChange the view controller's root view to off-white:</p>\n\n<ol>\n<li>Select the view controller's root view by either clicking on it in your storyboard or selecting it in the document outline. If you don't see it in the <em>Document Outline</em>, you might have to expand the <code>View Controller Scene</code> tree. Make sure you're not selecting the header view by accident. <a href=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P3-UI-Layout/assets/select_root_view.png\" target=\"_blank\">\n          <img src=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P3-UI-Layout/assets/select_root_view.png\" alt=\"Select Root View\" title=\"\">\n        </a>\n</li>\n<li>With the root view still selected, open the <em>Attributes Inspector</em> in the <em>Utilities area</em>. <a href=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P3-UI-Layout/assets/open_attributes_inspector.png\" target=\"_blank\">\n          <img src=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P3-UI-Layout/assets/open_attributes_inspector.png\" alt=\"Open Attributes Inspector\" title=\"\">\n        </a>\n</li>\n<li>Next, click on the blue dropdown button beside the active color for the <code>Background Color</code> field. <a href=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P3-UI-Layout/assets/click_bg_color_dropdown.png\" target=\"_blank\">\n          <img src=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P3-UI-Layout/assets/click_bg_color_dropdown.png\" alt=\"Click Background Color Dropdown\" title=\"\">\n        </a>\n</li>\n<li>Finally, select the <code>Off-White</code> color under the <em>Named Colors</em> subheader in the dropdown menu. <a href=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P3-UI-Layout/assets/select_off_white.png\" target=\"_blank\">\n          <img src=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P3-UI-Layout/assets/select_off_white.png\" alt=\"Select Off-White Background Color\" title=\"\">\n        </a>\n</li>\n</ol>\n</div><p>We've changed the <em>background color</em> attribute of the root view to a different color. The <code>Off White</code> color we chose was pre-defined in our <code>Assets.xcasset</code> asset catalog.</p><p>Before we add more views or configure more properties, let's learn about the iOS coordinate system and the frame attribute of <code>UIView</code> and it's subclasses. We'll need to learn about the iOS coordinate system to properly position and size our views.</p>"},{"id":"T0E6OlNlY3Rpb24tMTA3","title":"iOS Coordinate System","htmlContent":"<p>You can think of your phone screen as a coordinate system with it's origin in the top-left corner.</p><p><a href=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P3-UI-Layout/assets/ios_coord_system.png\" target=\"_blank\">\n          <img src=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P3-UI-Layout/assets/ios_coord_system.png\" alt=\"iOS Coordinate System\" title=\"\">\n        </a></p><p>As we've previously discussed, view can be represented as rectangles drawn on our device's screen. This rectangle can be represented by it's starting point (top-left corner of the rectangle) along with it's size (width and height). Let's look at an example:</p><p><a href=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P3-UI-Layout/assets/coord_example.png\" target=\"_blank\">\n          <img src=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P3-UI-Layout/assets/coord_example.png\" alt=\"Coord Example\" title=\"\">\n        </a></p><!-- break --><div class=\"challenge\">\n<p>\nIn the image above, what is the red view's starting point? What about it's size?</p>\n</div><!-- break --><div class=\"solution\">\n<p>\nAs you can see from the numbered X and Y axis, the view rectangle starts at the point (27, 48) in the iOS coordinate system and has a width of 50pts and a height of 35pts.</p>\n</div><p>In Swift, we have the <code>CGPoint</code> and <code>CGSize</code> data types to represent coordinate points and sizes respectively. A <code>CGPoint</code> value is a pair of X and Y values. A <code>CGSize</code> value is a pair of width and height values.</p><p>Additionally, these two data types can be combined into <code>CGRect</code> data type (X, Y, width, height) that represents a rectangle represented by it's point and size properties.</p><p>Each <code>UIView</code> has a property called it's <code>frame</code> of type <code>CGRect</code>. You can use each view's frame property to manipulate it's position and size.</p><div class=\"info\">\n<p>\nAt some point, you'll come across another view property named <code>bounds</code> that's also a <code>CGRect</code>. The <code>frame</code> of a view represents the view's rectangle in it's super view's coordinate system while it's <code>bound</code> property refers to the rectangle using the view's top-left corner as the origin of it's coordinate system. In other words, the <code>bounds</code> property of a view will always have an (x, y) of (0, 0) and retain it's size.</p>\n\n<p><a href=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P3-UI-Layout/assets/frame_vs_bounds.png\" target=\"_blank\">\n          <img src=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P3-UI-Layout/assets/frame_vs_bounds.png\" alt=\"Frame vs Bounds\" title=\"\">\n        </a></p>\n</div><p>With our new knowledge, let's properly re-position and re-size our header view.</p><h2>Setting The Header View Rect</h2><p>Looking back at our design, we can determine the <code>CGRect</code> of our header view.</p><div class=\"challenge\">\n<p>\nWhat should the <code>CGRect</code> (x, y, width, height) of our header view be?</p>\n\n<p><a href=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P3-UI-Layout/assets/nav_bar_dimensions.png\" target=\"_blank\">\n          <img src=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P3-UI-Layout/assets/nav_bar_dimensions.png\" alt=\"Header View Dimensions\" title=\"\">\n        </a></p>\n</div><!-- break --><div class=\"solution\">\n<p>\nThe <em>frame</em> of our header view is (0, 0, 375, 105).</p>\n</div><p>Let's change our current header view's frame in storyboard.</p><div class=\"action\">\n<p>\nIn <code>Main.storyboard</code> perform the following:</p>\n\n<ol>\n<li>Select the header view (UIView) in <em>Interface Builder</em>\n</li>\n<li>With the header view selected, open the <em>Size Inspector</em> in the <em>Utilities area</em>.</li>\n<li>Find the view's <code>Frame Rectangle</code> fields. Change the X, Y, Width and Height values in the size inspector to the value of the rect in the solution above.</li>\n</ol>\n\n<p><a href=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P3-UI-Layout/assets/fix_nav_bar_rect.png\" target=\"_blank\">\n          <img src=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P3-UI-Layout/assets/fix_nav_bar_rect.png\" alt=\"Fixed Header View\" title=\"\">\n        </a></p>\n\n<p>Let's see if our changes worked! Build and run the app in the iPhone 8 simulator by clicking the run button in the toolbar.</p>\n</div><p>You should see the custom header view against your off-white root view in the simulator. Nothing fancy yet!</p><p><a href=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P3-UI-Layout/assets/fixed_nav_bar_simulator.png\" target=\"_blank\">\n          <img src=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P3-UI-Layout/assets/fixed_nav_bar_simulator.png\" alt=\"Fixed Header Simulator\" title=\"\">\n        </a></p><p>But what happens if we run our app in a simulator with a different size screen?</p>"},{"id":"T0E6OlNlY3Rpb24tMTA4","title":"Handling Different Screen Sizes","htmlContent":"<p>Let's revisit our previous diagram explaining a view's frame within the iOS coordinate system.</p><p><a href=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P3-UI-Layout/assets/nav_bar_dimensions.png\" target=\"_blank\">\n          <img src=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P3-UI-Layout/assets/nav_bar_dimensions.png\" alt=\"Header View Dimensions\" title=\"\">\n        </a></p><p>What would happen if our app was ran across multiple different screen sizes?</p><p><a href=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P3-UI-Layout/assets/fixed_nav_bar_diff_screens.png\" target=\"_blank\">\n          <img src=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P3-UI-Layout/assets/fixed_nav_bar_diff_screens.png\" alt=\"Fixed Header View With Different Screen Sizes\" title=\"\">\n        </a></p><p>As you can see, the frame of the <code>UIView</code> needs to be different for each device with a different screen size.</p><div class=\"challenge\">\n<p>\nCan you think of some ways of how we could solve this problem?</p>\n</div><h2>Introducing Auto-Layout</h2><p>One way we could solve different frames for each screen size is by programmatically calculating and setting each view's frame. However, that would be super messy and lead to us having to write a lot of code just make sure each view is the right size for each screen.</p><p>To solve this problem, Apple created a relative positioning tool called <em>Auto-Layout</em>. With <em>Auto-Layout</em>, we define constraints.</p><p>Constraints are rules where you can define the relative positioning or size between two views. <em>Auto-Layout</em> will then calculate all the math and set our view's frame so that all of the constraints (rules) are followed. This allows us to build dynamic view layouts that re-position and re-shape for any screen size.</p><p>For example, we could give our example view the following constraints:</p><ul>\n<li>Top: 20pts from Super View (Root View) Top Edge</li>\n<li>Leading (Left): 40pts from  Super View (Root View) Leading Edge</li>\n<li>Trailing (Right): -80pts from  Super View (Root View) Trailing Edge</li>\n<li>Bottom: -380pts from bottom</li>\n</ul><div class=\"info\">\n<p>\nNote the positive and negative values that are based on the direction of the iOS coordinate system.</p>\n</div><p><a href=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P3-UI-Layout/assets/constraints_example.png\" target=\"_blank\">\n          <img src=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P3-UI-Layout/assets/constraints_example.png\" alt=\"Constraints Example\" title=\"\">\n        </a></p><p>Now if the screen changes, let's see how our view will react:</p><p><a href=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P3-UI-Layout/assets/constraints_example_diff_screens.png\" target=\"_blank\">\n          <img src=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P3-UI-Layout/assets/constraints_example_diff_screens.png\" alt=\"Constraints Example\" title=\"\">\n        </a></p><p>See how auto-layout calculates the view's frame based on our constraints for each different screen size?</p><p>If instead, we wanted give the view a fixed width or height, we can also add constraints as fixed constants. Let's give our example view a new set of constraints:</p><ul>\n<li>Top: 20pts from Super View (Root View) Top Edge</li>\n<li>Leading (Left): 40pts from  Super View (Root View) Leading Edge</li>\n<li>Width: 150pts</li>\n<li>Height: 200pts</li>\n</ul><p><a href=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P3-UI-Layout/assets/fixed_size_constraint_example.png\" target=\"_blank\">\n          <img src=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P3-UI-Layout/assets/fixed_size_constraint_example.png\" alt=\"Fixed Size Constraints Example\" title=\"\">\n        </a></p><p>Auto-layout and constraints give us an easy way to build dynamic view layouts for any iOS device.</p><h2>Determining Constraints</h2><p>Let's set our first constraints by changing our header view in <em>Interface Builder</em> to make use of constraints.</p><div class=\"challenge\">\n<p>\nWhat constraints should we set for our header view? <a href=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P3-UI-Layout/assets/nav_bar_dimensions.png\" target=\"_blank\">\n          <img src=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P3-UI-Layout/assets/nav_bar_dimensions.png\" alt=\"Header View Dimensions\" title=\"\">\n        </a></p>\n</div><!-- break --><div class=\"solution\">\n<p>\nOur header view would have the following constraints:</p>\n\n<ul>\n<li>Top: 0 from Super View (Root View) Top Edge</li>\n<li>Leading (Left): 0 from Super View (Root View) Leading Edge</li>\n<li>Trailing (Right): 0 from Super View (Root View) Trailing Edge</li>\n<li>Height: 105 fixed constant</li>\n</ul>\n</div><p>Looks pretty good. Let's look at our header view with these constraints across each device:</p><p><a href=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P3-UI-Layout/assets/nav_bar_w_fixed_height_constraint.png\" target=\"_blank\">\n          <img src=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P3-UI-Layout/assets/nav_bar_w_fixed_height_constraint.png\" alt=\"Header View With Fixed Height Constraint\" title=\"\">\n        </a></p><p>Hold on. Not so fast. With the introduction of the iPhone X, the sensor housing (the top notch) requires to add some additional thought to our header view frame.</p><p><a href=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P3-UI-Layout/assets/nav_bar_fixed_height_problem.png\" target=\"_blank\">\n          <img src=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P3-UI-Layout/assets/nav_bar_fixed_height_problem.png\" alt=\"Header View Fixed Height Problem\" title=\"\">\n        </a></p><p>Because the top notch, we'll need to make calculate the header view's height based on the bottom of the top notch for the iPhone X.</p><p>To help us handle this, Apple has provided us with the <em>Safe Area</em>.</p><h2>Safe Area</h2><p>The <em>Safe Area</em> provides us with valuable layout information to help us properly create constraints for our views. In our case, the top <em>Safe Area</em> provides us with the bottom of the <em>Status Bar</em> for each device:</p><p><a href=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P3-UI-Layout/assets/safe_area.png\" target=\"_blank\">\n          <img src=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P3-UI-Layout/assets/safe_area.png\" alt=\"Safe Area\" title=\"\">\n        </a></p><p>Revise our original constraints, we'll need to replace our height constraint with a bottom constraint that is -85 from the top <em>Safe Area</em>. Now our header view dynamically calculate it's layout correctly across each device.</p><p><a href=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P3-UI-Layout/assets/nav_bar_correct_height.png\" target=\"_blank\">\n          <img src=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P3-UI-Layout/assets/nav_bar_correct_height.png\" alt=\"Header View Correct Height\" title=\"\">\n        </a></p><p>It might be a little hard to see, but the height of the header view is slightly bigger for the iPhone X because of it's top notch.</p><p>With our correct constraints, let's set them in <em>Interface Builder</em>.</p><h2>Setting Our First Constraints</h2><p>Let's set our constraints in <em>Interface Builder</em>. First we'll start by adding our top, leading (left) and trailing (right) constraints.</p><div class=\"action\">\n<p>\nOpen <code>Main.storyboard</code> from your <em>Project Navigator</em>. Select your header view (<code>UIView</code>) and add the following constraints:</p>\n\n<p><video width=\"100%\" controls><source src=\"https://s3.amazonaws.com/mgwu-misc/Tip+Calculator+Swift+4/p3_ui_layout/edge_constraints_nav_bar.mp4\" type=\"video/mp4\"></source></video></p>\n\n<p>With our header view selected, we click on the <em>Add New Constraints</em> button and set each of the edge constraints:</p>\n\n<ul>\n<li>\n<em>Top Edge</em> of header view 0pts to <em>Top Edge</em> of root view</li>\n<li>\n<em>Leading (Left) Edge</em> of header view 0pts to <em>Leading (Left) Edge</em> of root view</li>\n<li>\n<em>Trailing (Right) Edge</em> of header view 0pts to <em>Trailing (Right) Edge</em> of root view</li>\n</ul>\n</div><p>Currently, our header view has a incomplete set of constraints. We haven't added a constraint to define the view's height yet. If we run the app now, we won't see our header view because it's height will be 0. Xcode and <em>Interface Builder</em> try to warn us of this:</p><p><a href=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P3-UI-Layout/assets/constraint_errors.png\" target=\"_blank\">\n          <img src=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P3-UI-Layout/assets/constraint_errors.png\" alt=\"Constraint Errors\" title=\"\">\n        </a></p><p>You'll notice above:</p><ol>\n<li>a red error arrow that lists missing constraints in your document outline</li>\n<li>red highlights around the custom header view in your storyboard</li>\n<li>a warning in the Xcode project status bar</li>\n</ol><p>Let's add the final constraint to define the header view's height.</p><div class=\"action\">\n<p>\nAdd a constraint from the bottom edge of the header view to the top edge of the <em>Safe Area</em>: <video width=\"100%\" controls><source src=\"https://s3.amazonaws.com/mgwu-misc/Tip+Calculator+Swift+4/p3_ui_layout/nav_bar_safe_area_constraint.mp4\" type=\"video/mp4\"></source></video></p>\n\n<p>To add the constraint in the video, follow the steps below:</p>\n\n<ol>\n<li>Select the header view (<code>UIView</code>) in the <em>Document Outline</em>.</li>\n<li>With the header view selected, hold down the control button (ctrl) and click-drag from the header view to the <em>Safe Area</em> view in your <em>Document Outline</em>.</li>\n<li>Once you let go, you'll see a pop-up with the options to add a new constraint. Select <em>Vertical Spacing</em>. This will set a vertical spacing constraint from the top edge of our header view to the top edge of the <em>Safe Area</em>.</li>\n<li>(Optional) If you'd like to adjust the constraint, you can click on it and adjust it's values in the <em>Size Inspector</em>.</li>\n</ol>\n</div><p>Congrats, we've added our first set of constraints to our header view. Try running your app in multiple different simulators and see if our header view properly adjusts it's frame to each device.</p><p><a href=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P3-UI-Layout/assets/dynamic_nav_bar_diff_devices.png\" target=\"_blank\">\n          <img src=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P3-UI-Layout/assets/dynamic_nav_bar_diff_devices.png\" alt=\"Auto-Layout Header View Multiple Devices\" title=\"\">\n        </a></p><p>It works! Next, we'll dive deeper into <em>auto-layout</em> and the different kind of constraints that are available to use.</p>"},{"id":"T0E6OlNlY3Rpb24tMTA5","title":"Different Types of Constraints","htmlContent":"<p>To properly setup constraints for our header view, we've only used one type of constraints but there are many different types of constraints that you can use to build complex UI layouts. Before setting up constraints for any of our other fews, let's look at common constraints we can use to build dynamic layouts with <em>auto-layout</em>.</p><h2>Relative Positioning</h2><p>First, let's review our relative positioning constraint. Relative positioning allows to position a view relative to another view. For example, we can create a constraint that positions the blue view 45pts from the trailing (right) side of the red view:</p><p><a href=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P3-UI-Layout/assets/relative_positioning_positive.png\" target=\"_blank\">\n          <img src=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P3-UI-Layout/assets/relative_positioning_positive.png\" alt=\"Relative Positioning Positive\" title=\"\">\n        </a></p><p>Positive and negative values (relative to the iOS coordinate system) denote the direction of the constraint. For example, we can instead add a constraint that positions the blue view -75pts from the trailing (right) side of the red view:</p><p><a href=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P3-UI-Layout/assets/relative_positioning_negative.png\" target=\"_blank\">\n          <img src=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P3-UI-Layout/assets/relative_positioning_negative.png\" alt=\"Relative Positioning Negative\" title=\"\">\n        </a></p><div class=\"info\">\n<p>\nWhen you're creating relative positioning constraints, you'll need to keep in mind which view's edge the constraint is starting from, the other view's edge where the constraint is ending at and the position or negative value (direction) of the constraint.</p>\n</div><p>When you're setting your relative positioning constraints, make sure you're aware of what they're relative to. For example, let's set the blue view 20pts below the red view:</p><p><a href=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P3-UI-Layout/assets/relative_positioning_top_edge.png\" target=\"_blank\">\n          <img src=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P3-UI-Layout/assets/relative_positioning_top_edge.png\" alt=\"Relative Positioning Top Edge\" title=\"\">\n        </a></p><p>But is that what we wanted? In the case above, we set our blue view to have a constraint of 20pts below the red view but relative to the wrong edge of the red view!</p><p>This is probably what we really intended:</p><p><a href=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P3-UI-Layout/assets/relative_positioning_bottom_edge.png\" target=\"_blank\">\n          <img src=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P3-UI-Layout/assets/relative_positioning_bottom_edge.png\" alt=\"Relative Positioning Bottom Edge\" title=\"\">\n        </a></p><p>As you can see, it's a very common mistake to accidentally set constraints relative to the wrong edge or sometimes even the wrong view!</p><div class=\"info\">\n<p>\nIt's also important to take the <em>Safe Area</em> into consideration when setting a view relative to the root view. If you're setting the top edge of your view to the top edge of the root view, you'll need to verify that you don't accidentally set it to the top edge of the <em>Safe Area</em> instead, or vice versa.</p>\n</div><h2>Constant Size (Height or Width)</h2><p>As we briefly discussed earlier, it's also possible to set fixed constant constraints. These are used to set a fixed width or height of a view. For example, we can give a view a fixed width and height of 100pts:</p><p><a href=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P3-UI-Layout/assets/fixed_size_constraints.png\" target=\"_blank\">\n          <img src=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P3-UI-Layout/assets/fixed_size_constraints.png\" alt=\"Fixed Size Constraints\" title=\"\">\n        </a></p><p>In this case, the red view will always remain the same size (100x100) regardless of changing screen sizes.</p><div class=\"info\">\n<p>\nIf you run into a situation where you've added your constraints but don't see your view, you might have forgotten to add certain constraints. Remember, each view's frame must be able to be determined by it's auto-layout constraints.</p>\n\n<p>In the previous example, if we forgot to add the height constraint, our view wouldn't show up because the height of it's frame is 0.</p>\n</div><h2>Center (With Offset) In Superview</h2><p>Another positioning constraint we can use is aligning center axes vertically or horizontally. For example, we can create a constraint that vertically aligns the blue view's center to red views:</p><p><a href=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P3-UI-Layout/assets/centers_vertically_aligned.png\" target=\"_blank\">\n          <img src=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P3-UI-Layout/assets/centers_vertically_aligned.png\" alt=\"Centers Vertically Aligned\" title=\"\">\n        </a></p><p>Or we horizontally align the two views:</p><p><a href=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P3-UI-Layout/assets/centers_horizontally_aligned.png\" target=\"_blank\">\n          <img src=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P3-UI-Layout/assets/centers_horizontally_aligned.png\" alt=\"Centers Horizontally Aligned\" title=\"\">\n        </a></p><p>You can also choose to offset (positive or negative to determine direction) from the superview:</p><p><a href=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P3-UI-Layout/assets/centers_vertically_aligned_offset.png\" target=\"_blank\">\n          <img src=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P3-UI-Layout/assets/centers_vertically_aligned_offset.png\" alt=\"Centers Vertically Aligned Offset\" title=\"\">\n        </a></p><h2>Aspect Ratio</h2><p>Aspect ratio constraints are also available. You can set the height to be a ratio of the width or vice versa. This can be useful if you want to make sure the view is always a square (1:1 aspect ratio) or if you decide that the height will always be 1/2 of the width (1:2 aspect ratio).</p><p>In the following example, we set the aspect ratio to (1:3) where the height is a third of the width:</p><p><a href=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P3-UI-Layout/assets/aspect_ratio.png\" target=\"_blank\">\n          <img src=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P3-UI-Layout/assets/aspect_ratio.png\" alt=\"Aspect Ratio\" title=\"\">\n        </a></p><h2>Equal (Ratio) To Other Constraint</h2><p>The last constraint that we'll cover is the ability to set constraints relative to the ratio of another constraint. This is useful when we want certain views to size themselves relative to other views. For example, we can set the height of the blue view to be (1:2), or half, of the red view:</p><p><a href=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P3-UI-Layout/assets/relative_ratio.png\" target=\"_blank\">\n          <img src=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P3-UI-Layout/assets/relative_ratio.png\" alt=\"Relative Rati0\" title=\"\">\n        </a></p><p>In our tip calculator, we'll use this constraint to size the input and output cards to be of equal heights.</p>"},{"id":"T0E6OlNlY3Rpb24tMTEw","title":"Setting Auto-Layout For Our View Grouping","htmlContent":"<p>Let's take an other look at our design:</p><p><a href=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P3-UI-Layout/assets/tc_design_reference.png\" target=\"_blank\">\n          <img src=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P3-UI-Layout/assets/tc_design_reference.png\" alt=\"TC Design\" title=\"\">\n        </a></p><p>Next, we're going to setup the main views (and their constraints) for each UI group. In other words, we'll add the objects and constraints below:</p><p><a href=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P3-UI-Layout/assets/ui_groups_with_dimensions.png\" target=\"_blank\">\n          <img src=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P3-UI-Layout/assets/ui_groups_with_dimensions.png\" alt=\"UI Groups With Dimensions\" title=\"\">\n        </a></p><h2>Implementing Our Constraints</h2><p>We've already finished implementing the foundation for our header view. We'll repeat a similar process for each of our remaining UI groups.</p><p>With our header complete, let's move on to implementing the tip input card.</p><h3>Input Card View</h3><div class=\"action\">\n<p>\nOpen <code>Main.storyboard</code>. Add a new <code>UIView</code> and set the following constraints:</p>\n\n<p><video width=\"100%\" controls><source src=\"https://s3.amazonaws.com/mgwu-misc/Tip+Calculator+Swift+4/p3_ui_layout/add_input_card_w_constraints.mp4\" type=\"video/mp4\"></source></video></p>\n\n<p>Step by step:</p>\n\n<ol>\n<li>Drag a <code>UIView</code> from the <em>Object Library</em> onto the root view.</li>\n<li>Click the <code>Add New Constraints</code> button at the bottom right corner of the <em>Interface Builder Editor</em> window.</li>\n<li>Set the following constraints:\n\n<ul>\n<li>(Input Card) <em>Top Edge</em> 24pts from Header View <em>Bottom Edge</em>\n</li>\n<li>(Input Card) <em>Leading (Left) Edge</em> 15pts from Super View (Root View) <em>Leading (Left) Edge</em>\n</li>\n<li>(Input Card) <em>Trailing (Right) Edge</em> 15pts from Super View <em>Trailing (Right) Edge</em>\n</li>\n</ul>\n</li>\n</ol>\n</div><p>At this point, you'll see an <em>auto-layout</em> error because your new (input card) view is missing a height constraint. Ignore this warning for now, we'll fix this soon.</p><p>Next, we'll add our output card and it's constraints.</p><h3>Output Card View</h3><div class=\"action\">\n<p>\nIn storyboard, add a new <code>UIView</code> and set the following constraints:</p>\n\n<p><video width=\"100%\" controls><source src=\"https://s3.amazonaws.com/mgwu-misc/Tip+Calculator+Swift+4/p3_ui_layout/add_output_card_w_constraints.mp4\" type=\"video/mp4\"></source></video></p>\n\n<p>Step by step:</p>\n\n<ol>\n<li>Drag a <code>UIView</code> from the <em>Object Library</em> onto the view controller's root view, below the input card.</li>\n<li>Click the <code>Add New Constraints</code> button at the bottom right corner of the <em>Interface Builder Editor</em> window.</li>\n<li>Set the following constraints:\n\n<ul>\n<li>(Output Card) <em>Top Edge</em> 24pts from Input Card <em>Bottom Edge</em>\n</li>\n<li>(Output Card) <em>Leading Edge</em> 15pts from Super View <em>Leading Edge</em>\n</li>\n<li>(Output Card) <em>Trailing Edge</em> 15pts from Super View <em>Trailing Edge</em>\n</li>\n</ul>\n</li>\n</ol>\n</div><p>We'll also add an equal height constraints between both input and output card views.</p><div class=\"action\">\n<p>\nAdd an equal heights constraint between both input and output cards:</p>\n\n<p><video width=\"100%\" controls><source src=\"https://s3.amazonaws.com/mgwu-misc/Tip+Calculator+Swift+4/p3_ui_layout/add_cards_equal_height_constraint.mp4\" type=\"video/mp4\"></source></video></p>\n\n<p>Step by step:</p>\n\n<ol>\n<li>Select the output card view.</li>\n<li>With the output card selected, hold down shift and then click on the input card view. This will allow you to select both card views.</li>\n<li>Click the <code>Add New Constraints</code> button at the bottom right corner of the <em>Interface Builder Editor</em> window.</li>\n<li>In the popup prompt, select <code>Equal Heights</code> and add the selected constraint.</li>\n</ol>\n</div><p>Xcode should still show an <em>auto-layout</em> error because we haven't added enough constraints for it determine the height of each card view. Ignore this warning for now, this will be fixed once we add our reset button.</p><h3>Reset Button</h3><div class=\"action\">\n<p>\nIn storyboard, add a new <code>UIButton</code> and set the following constraints:</p>\n\n<p><video width=\"100%\" controls><source src=\"https://s3.amazonaws.com/mgwu-misc/Tip+Calculator+Swift+4/p3_ui_layout/add_reset_button_w_constraints.mp4\" type=\"video/mp4\"></source></video></p>\n\n<p>Step-by-step:</p>\n\n<ol>\n<li>Drag a <code>UIButton</code> from the <em>Object Library</em> onto the view controller's root view, below the output card.</li>\n<li>Click the <code>Add New Constraints</code> button at the bottom right corner of the <em>Interface Builder Editor</em> window.</li>\n<li>Set the following constraints:\n\n<ul>\n<li>(Reset Button) <em>Top Edge</em> 24pts from Output Card <em>Bottom Edge</em>\n</li>\n<li>(Reset Button) <em>Leading Edge</em> 15pts from Super View <em>Leading Edge</em>\n</li>\n<li>(Reset Button) <em>Trailing Edge</em> 15pts from Super View <em>Trailing Edge</em>\n</li>\n<li>(Reset Button) <em>Bottom Edge</em> 24pts from Super View <em>Bottom Edge</em>\n</li>\n<li>(Reset Button) <em>Height</em> of 60pts</li>\n</ul>\n</li>\n</ol>\n</div><p>By default, our button has a clear background color. To make our reset button easier to see, let's change it's background color from <code>Clear</code> to <code>tcDarkBlue</code>.</p><div class=\"action\">\n<p>\nChange the <em>Background color</em> of the reset button:</p>\n\n<p><video width=\"100%\" controls><source src=\"https://s3.amazonaws.com/mgwu-misc/Tip+Calculator+Swift+4/p3_ui_layout/set_reset_button_bg_color.mp4\" type=\"video/mp4\"></source></video></p>\n\n<p>Step-by-step:</p>\n\n<ol>\n<li>Select the <em>Reset Button</em>.</li>\n<li>With the <em>Reset Button</em> selected, navigate to the <em>Attributes Inspector</em> in the <em>Utilities area</em>.</li>\n<li>Scroll down until you find the <code>Background</code> field. This field allows you to set the button's background color.</li>\n<li>Locate the blue dropdown button and set the button's background color from <code>Clear</code> to <code>tcDarkBlue</code>.</li>\n</ol>\n</div><!-- break --><div class=\"info\">\n<p>\nOur <em>auto-layout</em> warning is gone! After adding our reset button and it's constraints, <em>auto-layout</em> can calculate the height of each input/output card using the equal heights constraint.</p>\n</div><p>We've finished implementing the main view for each of our respective UI groups. For each group, we added the appropriate <code>UIView</code> object and set it's corresponding constraints.</p><p>Before moving on, let's test that everything looks as expected.</p>"},{"id":"T0E6OlNlY3Rpb24tMTEx","title":"Testing Our Constraints","htmlContent":"<p>To catch bugs or missteps early, it's always good to build and run your code often. Let's go ahead and do that now to test that our constraints are working correctly.</p><div class=\"action\">\n<p>\nIn the toolbar, click the <em>Run</em> button.</p>\n</div><p>If everything goes as expected, you should see the following in your simulator:</p><p><a href=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P3-UI-Layout/assets/finished_ui_groups.png\" target=\"_blank\">\n          <img src=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P3-UI-Layout/assets/finished_ui_groups.png\" alt=\"Finished UI Groups\" title=\"\">\n        </a></p><p>Try running our project on different simulators. You'll notice that our view dynamically adjust and re-size for any screen size:</p><p><a href=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P3-UI-Layout/assets/finished_ui_groups_diff_devices.png\" target=\"_blank\">\n          <img src=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Tip-Calculator-Swift4@9457825dfd233448537fd0fa62707e9211e8bfb8/P3-UI-Layout/assets/finished_ui_groups_diff_devices.png\" alt=\"Finished UI Groups Different Devices\" title=\"\">\n        </a></p><h2>Conclusion</h2><p>In this section, we learned about how to layout our UI; first with frames and later with <em>auto-layout</em>. We learned about constraints and their importance in building dynamic view layouts for multiple devices. And finally, we put our knowledge into practice by implementing a scaffolding for our tip calculator design.</p><p>In the next section, we'll build off of our UI by fully implementing and styling each of our UI groups.</p>"}]},"next":{"id":"T0E6OlBhZ2UtMzk=","slug":"implementing-subviews","title":"Implementing Subviews"},"previous":{"id":"T0E6OlBhZ2UtMzk=","slug":"implementing-subviews","title":"Implementing Subviews"}}}},"staticQueryHashes":[]}