Transcripts
1. Course Overview: Hello, My name is Jeff, and welcome to the IOS Fundamentals Course where we're going to build our first application that looks like this. This course assumes that you have basic programming experience and you're wanting to learn more about IOS application development. This course is comprised of 20 video tutorials for each video, covers a specific IOS topic and then applies that topic towards building out our application. Each video in the Siri's builds upon the videos that came before it so that you can code along in your own project for each step of the way to succeed in this course, make sure that you understand the topic covered in each video, and it would be beneficial to code along for each video in the series. The final project for this course uses many of the skills that we learned and applies them towards a new app with a different set of requirements. Thank you for enrolling in this course, and I look forward to seeing you in the first video tutorial
2. Getting Setup: The very first thing we need to do is get X code set up. X Code is Apple's primary integrated development environment, and it's what we're going to be using for this entire tutorial. So if you're on a Mac computer, if you go to the APP store and you search for X code, it should be the first thing that comes up. So we want to do is download X code, and once Ex Card is downloaded, go ahead and open it and will create our first project. Most Ex card is opened and set up. Go to the Create a new project and you'll be greeted with a menu that looks like this. Make sure you're on the IOS section and we're going to select a single view application. You'll notice here that there's a few other template types, such as a page based at a tab base up and a few other ones. But our intents and purposes we want to use a single view app, so go ahead and hit next, and we need to go ahead and give this project the name so we'll just call this Project one and you'll need to select an organization and for a team I'm gonna put my team is none because I'm not using any developer profile associated with this right now for the organization name in the organisation. Identify where you can come up with a new organization name that you feel is appropriate in an identifier. You can also come up with your own identifier for that as well. For the language we're going to be using Swift and for the unit tests here, I'm going to uncheck this box. We're not going to be doing any testing in this interrogatory ALS Siri's so once all that set up, let's go ahead and hit next and place the project anywhere we want it. And once we've done that, we can go ahead and start taking a look at what we have inside of this project structure. So let's take a quick look at how the project is structured. If we go here to the top left. This blue icon is what's known as our Project file, and it contains pretty much all of the source code files, the user interface files. It knows where every file in our project lives and has a reference to it When we select our project file, we see that we have a section here called targets. Targets are basically the app. The app that we're building is an app called Project One and an APP bundle contains all of the resource is and the compiled code that builds up our app in all the logic inside of it . So when you select the target or basically selecting your app, you can see that you have these tabs appear, such as general capabilities, built settings and build phases. There's lots of different little bits of information in here that we might need to change over time. But under general is where you'll find things such as the display name of the app, the bundle identify where the version the team that you're using for your developer team, as well as many other settings such as the deployment, target, the devices and so on and so forth. So a lot of times we have to have an understanding of the things that we can change in here if we have to modify project settings for our application. So going back over on the left, we have our swift files. These are the source code files were gonna be writing most of our logic in the application . Next, we have what's known as a storyboard file, and this is the visual representation of our application. As we start to create different screens in the APP, we can add different you elements to this story board to construct a visual layout of where APP is gonna look like and how it's going to flow. Also, we have what's known as an Assets folder. This is where we'll put things such as an app icon are icons for different resource is in our lab and different screens and views, maybe a profile image. We'll put those in here as well as other assets step along in the assets catalogue. We want to make sure that our project compiles and builds and runs on our simulator successfully, so to actually run the application. If we go up here, we see we have this play button that gives us different options. If we click on it, we have the option to run to test to profile on analyzer application. So before we run it, we want to make sure that we select the application target, which is Project one for our example as the selected project in here. The selected target. Now, once you have that, you should have an option of simulators to select from. I'm going to choose an iPhone SC simulator just to run this on to make sure that it works. If you don't have any simulator showing up for whatever reason, if there is an installation issue, you have the option. Here it's you download simulators, and if you click that, it will take you into the list of simulated run times that you can download. And once that completes, you'll have a list of simulators that show up in this man. You drop down. So once you've selected your simulator, go ahead and hit the play button and that's going to compile the project, build up our application bundle and install it onto the simulator, and so far it looks like everything's good. You can see that, says launching Project one, and we'll just give this minute the simulator minute to boot up and verify that everything's looking good. My simulator is up and running, and I see a white background, which is a good sign, and if we go back over to our main story board and select it so that it shows up here and we go back and take a look at our simulator. What we're seeing in our simulator right now is the visual representation of this view controller from the storyboard, you can see that there's no you I interface elements on this view controller, such as a text field or any kind of buttons, and it's a white background. And since this is the starting view controller, that's what's being presented right here in the simulator. So now let's take a deeper look into view controllers and understand a little bit more about how they are the bread and butter of an IOS application.
3. All About View Controllers: now go ahead, select to the view controller inside the main story board and go down to the bottom left corner here. And make sure you expand this document outlined menu option. And when you do, you'll have your view controller hierarchy here, and you can see that with his view controller. It contains a view, and a view controller is the bread and butter the building blocks of an IOS application. You can think of a view controller as a screen in an app that could contain any number of you elements such as text fields and other views and table views. So on and so forth when we wanted for additional screens in our application. For the most part, we're going to create some form of a view controller, and we're going to navigate from view controller to view controller, passing data from one to the other to navigate through our app through what's known as Segways. And essentially, the view controller can just simply is that it's a controller that controls views, and that's its job in primary purpose. So if we want to add elements to a view controller, what we can do it from a storyboard stamp perspective is, if we go down here to the object library and start looking through the selected selection of options here, we can drag elements onto the view. So let's say, for example, I wanted to add a text field that starts for Text Field and I get an option here. And Aiken, drag it over onto the view controller. And if you go back and look at the hierarchy here, you can see that this view contains a sub view for a sub component. And that is the text field. And generally, that's how we're going to design most for you elements in this course. It's great for beginners. It's visually easy to see, and it represents the flow of our application, and we can move forward quite quickly by doing this approach. So now that we have a basic understanding, have have you controllers work inside of a storyboard file, we need to understand how they relate back to the source code files. So if you go over here and you go to the assistant editor icon and click it, it's gonna open up the side panel and we can have our view controller dot swift file side by side with our view controller from the storyboard. And as we kind of look here, if we select our view controller and we go back over here to the right side and we go to the class, Inspector, you can see that there is a class called view controller. So by default, the view controller that is created in the project is automatically assigned to this source code file right here. And as we create additional view controllers, we have to assign the source code file to map to the corresponding view controller in the storyboard file. So let's do that for an example. Just so you haven't understanding of how to actually accomplish that. So go back down here to the object library. What we want to do is look for a view controller and we can drag that element onto our storyboard here. And so now we have a second you controller. It doesn't have a subclass or any kind of association with source code file. We're gonna create that right now. So select a new view controller that you just created and go over to your source code. And under your folder, right click and go to a new file and we're gonna use a new swift file here, and we're gonna call this detail view controller, and we're gonna go ahead and create that file. Now, make sure you have your detailed view. Control are selected here, and I'm gonna actually bring it up in my right hand side. If I click this menu and going to recent files, I can look for detailed view controller. If you see interface, don't click that one. Make sure you quit the one that does not say interface. So that will bring up the code file here on the left side. Let's keep our storyboard open and let's go ahead and make the association between this code file and this you element here. So we need to actually create our class. And we do that by importing in the necessary framework that contains view controllers. And what we'll do is important. You I kids, I'll explain in a minute why we need to do this. So we need to create our class class detail view controller, which derives from you. I view controller and let's go ahead and get that structured. And let's add a method here called View, did load and we'll just do a super job. You did load and let's let's break down exactly what's going on by what we just did. So the U I view controller is from the apples. You I kit framework. It contains the base level you I controls that Apple provides for us to use in our application development for Iowa's. And basically we're saying there are detailed view controller is is it subclass ing or not subclass ing but arrives from you. I view controller. So it contains all of the properties and elements there which comes from you. I kit. Now, how do we make this association from here to here? Well, that's quite easy. If you select the view controller in the storyboard and we go back over to the class inspector here now we have the opportunity to create our sub classing. And so if you see right here is looking for any kind of you have you controller and we just happen to make one called a detailed view controller so we can create the association here by typing in detail, view controller and you could see executes automatically populating that for us. And one other thing we want to do here is set up a storyboard. I d. And generally what all uses the name of the class as the name of the storyboard I d. And that basically means that when we're looking to load the view controller programmatically maybe we can always look for it by its name, which is detailed view controller toe, load it into the code. So once you've got that set up, you've now created the link between the source code file in the U. S. In the U element here. So let's take a look at viewed load. If we command click onto you, have you controller and go to jump the definition. This is where we can see all of the different methods available that Apple provides for us that we can use the from of you. You have you controller. You can see right here. That's where view did load is coming from. And it says right here in the comments called after the view has been loaded for view, control is created and code. This is after a lot of you. And generally this is where we do most of not all of our set up code for most circumstances is when this method gets called. So it's very important that we override this in our subclass to view controller, and we'll definitely be getting into more of these lifecycle methods as we move forward.
4. Segues and Navigation Controllers: Now let's talk about Segways, Segways or how we transition from one view controller to another view controller. And we can do it through a few different ways. And what we're going to start with is what's called a motile Segway. And to do so, we want to do a couple of things. So the first thing we want to do on our detail of you controller is will change the color of the view so that we can visually distinguish which view controller were on. So if you have your detailed new controller selected here, if you go over and you find the view here and selective you and then you go over here, we want to select the tab for the attributes. Inspector, we go down to the views, background color, and I was gonna change mind to a different color here, so we can visually see that this is the detail screen. Now, in order to trigger the Segway, we need some kind of button click where you element that a user would interact with to get from one to the other. And we can go down to the object library here and look for a button and we can drag that button over onto our first view controller, and I'm going to leave the text field that I had in there from earlier. And we all do is put the button kind of in the center. I'm going to drag it forward, and I'm zooming a little bit on the canvas here and just kind of increase the within the height of the button and center it. And if you go over here with your button selected, we've used instead of the default text button. Well, just dio say where and what we need to do next is actually create the connection to do the Segway. Now the easiest way to do it is an interface builder, and by doing that, we can hold our selector button. We can hold down the control key on the clean up on the keyboard, click and then drag over to detailed view, controller and release, and you'll see that we have an action Segway that comes up. We have a show, a show detail, present mode early, and then we have these non adaptive deprecate ID Segways. So what we're gonna do is a show and you'll see right away that that creates the connection from here to here. So let's run this in the simulator and see exactly what this will look like. My simulators up and running here. And don't worry if your buttons a little off center as long as you can still see it, that's fine. We'll talk about how to position in, lock things in with auto layout later on in the series. If right now, go ahead and hit the Segway button and you can see that we went to our detailed view controller, we have a real a screen here, but unfortunately we don't have any way to get back to our starting view controller. We're stuck here because we have no way to dismiss the flow. You see, we don't have any back button or way to go down. And this type of Segway is known as a motile Segway. It's used to present information that would take up the full screen, and presumably it would be used to capture some kind of user input like, let's, say, an entry form a registration form, a log inform upon which still had somebody to dismiss the flow. Now, obviously, we haven't added a button here, so we're stuck for the moment. Now we can easily rectify this with what's called a navigation controller. Now what you'll do next is go back to your story board and select the actual Segway and delete it. And what will do instead is we're going to introduce this idea of a navigation controller. And the easiest way to set up this view controller with a navigation controller is select your new controller, go to the editor menu here, go to embed in and then select navigation controller. And right away. What you're going to see is we have this navigation controller that's pointing to our view controller at the very top. Here we have a navigation bar, and this is gonna be important in a moment. So let's repeat the same steps. We're going to connect our button here to the detailed view controller here. So if we hold down the control key, click and drag over. We have our action. Segway come up and we're going to do show and you'll see now that we have a back button on our detailed view controller that we didn't have before. So let's go ahead and run this in the simulator, and then we'll go through a discussion about navigation controllers and what exactly is going on here? So now if I click my Segway button here, you'll see that we go into the detail view controller. But we have a way to get back. We have a back button, we press back button, we go back. If we had Segway again, we go forward, and you can also see that the animation is different. It's almost like it slides in, and one other thing you can do here is if you kind of drag on the edges a little bit, you have the ability to drag across to go back as well. And that's just a feature of navigation controllers they supported by default, unless you turn it off. And if you remember, the motile Segway or the first segment that we did came up from the bottom and our navigation controller, Segway slides over to the side. Now let's dig into navigation controllers a little bit. The navigation controller is a type of you I view controller. In fact, the navigation controller derives from you, have you controller, so it inherits all the properties that have you controller has, but it adds on a navigation bar and a array of you controllers that the navigation stack manages. You can think of Seguin between view controllers as pushing and popping view controllers onto and off of the stack. The internal stack of you controllers that the navigation controller contains. So by default, when you add a view controller through the storyboard and you connected through a Segway. Whatever this detail view controller is, or any other view controllers that derive from this navigation controller we'll all inherit the navigation bar, which provides a back button or a way to go back unless we turn it off for change it to do something else. Well, then you might ask yourself, which type of sake wait, do I use doing is a model or do I use a navigation controller? And that really depends on the flow of you controllers in your project and what you're trying to do. So if you have the standalone view controller that you can present from anywhere, and maybe it is going to collect to user information in a form or in a tutorial or a splash logo or something that could be presented, then dismissed. A model Segway would make the most sense now in a series of screens like this where you have, ah kind of a parent child relationship or a master detailed view relationship than having an especially if they needed navigation Bar. The navigation controller makes perfect sense because you can start with one view and drill down into a series of views that are all interrelated, and then you can easily navigate your way back up the stack to the parent view controller.
5. Understanding Table View Controllers: so far we've touched on you, have you controllers and navigation controllers, and we have a little bit of an understanding of how to move around in an application. But in order to build a to do list app, we need basically a list. So what we really need in terms of a list for Iowa's is a table view, and specifically we're going to use a specialized form known as the table of you controller . Now, a table of your controller is nothing more than a specialized. You have you controller that contains a table view in implements, some of the methods and functionality that is needed for a table of you to display its data and to customize the cells or the rows of the data. So if we go down to our object library here, when we search for table view controller, you'll see that we have one that comes up in the list. And if we go ahead and drag that owns that the canvas, we can see right away that we have a table view, a cell or a table you sell, and that's given to us by default, just from using a table of you controller. And if we select our table view controller here and go into the document hierarchy, if we look here and we see that we have a table of you, the actual cell and then the content view of that cell and that's what we're going to start for our to do list is we're going to start structuring and setting up our table view controller so that it can be able to load our to do list items and allow us to add new to do list items and make selections to drill into the details view for items that we select from the list, just like we did with our detail view controller. We want to hook up a swift source code file to our corresponding table view controller right here. So let's go ahead and do that. Now go over to the project's file here and into the source code folder and right click the folder and do a new file and select a swift file. And I'm going to call mine to do list table view controller, and I'm gonna create that and right away we need to go ahead and do our usual important of you like it, which contains the class and all of the methods and functionality for table view controllers as well as you have you have you controllers to and we'll do class to do list table view controller. And it's going to derive from you I table view controller. And let's override the view did look method, which will be our entry point once this view controller loads for the first time. And once we have that set up here, make sure you're in the assistant editor. If your assistant editor is closed, you can open that just by clicking the button right here to open it. And let's go ahead and get our storyboard open on one side and I'm gonna put mine on the right side here and let's just look, let's make sure we have our table view controllers selected and we'll go to the class inspector here and where it says you want Table view controller. We're gonna change that to the to do list table view controller. We're also going to copy that name. Use it for the storyboard i d. In the restoration I d. So that way we can find it by the same name. And now let's actually take a look at what you I table view controller has so you can start just that commands clicking onto you. I take the view controller, which will take us into the documentation for this class. So looking at your table view controller, we can see a couple of things. If we look at the inheritance hierarchy and the protocols that it conforms to, it derives from you, have you controller? So right away, U. S. A. With the controller contains all of the functionality or inherits the functionality that the view controller exposes. But in addition to that, it has its own table view, which is what makes it the table view controller as well as implementing the table view delegate in data source particles. And we're gonna get to technical in depth on that for right now. But what's important to know is that this is just another specialized. You have you controller that contains a table view and lets us do various operations on elements in that list in that table of you. So now let's actually go back and start shuffling some things around in our storyboard. What we want to Dio is replace our view controller one with the Segway button and remove it completely. Our to do list table view controller is going to take its place instead. So what we can Dio is select our Segways from the view controller to the detail and we'll go ahead and hit the delete key to remove that at the same time, we're going to completely delete this view controller and its navigation controller so we can kind of to select both of those and deleted from here. It's easier sometimes if you selected from the, uh, hierarchy seen over here. And I'm gonna do the same thing for the navigation controller. Now, over here in the project source code. I'm also going to remove you Controller that swift. We're not going to use that anymore. And we're gonna replace that with our to do list table view controller So we'll get rid of that for now. And we're gonna bring our to do list table view controller back, and we are going to put it inside of a navigation controller the same way we have done with our view controller so selected we'll go to the editor and then we'll do embedded a navigation controller. And so right now, our table view controller just inherited a navigation bar and it has a table of you. So it has a lot of the things that we need to build out a to do list. And one other thing we need to remember to do is if we were to run this right now, we need to make sure that we have to find these starting view controller. So in this case, since the navigation controller is the first element that's going to be loaded, make sure that it is the starting view controller. And we can do that by selecting it, going over to the attribute inspector here. And it a little check box is initial view controller. Make sure you have that checked and you'll know because you have this little gray arrow here indicating that this is the starting view controller in this storyboard file. And so let's go ahead and run that right now, and we're not gonna see anything, but let's make sure that everything works in our simulator. So I look at what appears to be an empty list. My table view controller is running. It's the starting view controller, but there's nothing in it. I can kind of drag around a little bit, and if you can see that my table view bounces as I move around, Um, but other than that is nothing more than an empty list with the navigation bar at the top until we start actually implementing the code to hook up our data source and display elements in the list, and that's we're gonna start to do right now.
6. Implementing the TODO List: now, in order to create any list, we need items to do for tasks. So we're going to create a data model that represents a task. And if we go over to our project file hierarchy over here and we're gonna create a new swift file to represent this task, so right click and do new final pretty swift file. And let's just call this task type and we're gonna create another file. So go back to the folder, right Click New file, and we're gonna actually create a task, so we'll just call this one task. Now, the task type is going to define the category that our task will fall into. And this will just be any newme of type task type, and we'll create different categories. Represent this. So maybe we have a case for studying a case for house work, a case for coating, and it may be a case for vacation planning, and I think that's good for right now. So we have a few different kinds of tasks that we define for what we're interested in to finding it for and now we're gonna go back to the task that swift and create a new class to represent this so class task, and this class is going to contain a few properties. So we're gonna have a let task title. We'll just call it titled of Type String. Let due date, the type date and let type of task take. And one thing we'll do here is we'll make these private so that their only contained in this class. And then we need an initial Isar to inject in values for each one of these private properties. So you have an initial Isar and that initial izer is going to contain a title type strength , a due date type date in a type, the task tape and what we'll do inside the body of this initial izer is a sign each one of these injected values to our private properties in the class, so self titled equals title self due date equals Due date and self. That type equals type and make sure don't have any compilation issues. Go ahead and do command be or you can go up here to the product and build, and you see command to be is the hot key to represent that. Let's just make sure that our code compile successfully. It looks like it does. So now, with our data model set up, we need to go ahead and create instances of tasks and add them to the list here so that we can see them visually represented as Rose in our table view. So now we need to actually go back to our to do list table of you controller. And when we do so, we need to actually start writing a little bit of code here. So right away we have our table in controller. That sub classes you I table view controller derives from it. And the first thing we need to do is create a data source, and the data source is gonna contain all the rose for a table view and will define that like this Private, Our data source of type A collection of tasks equals an empty list to start off. And what we're gonna do here is create a private function, construct data source, and we're gonna call that right after our view loads. So we'll just call construct data source here. Now, what this method is going to do is create a couple of tasks in append them to our data source array. So what we'll do here is data source that depend. And we'll right inside of that, A new task. So we'll do task and we'll do title for the 1st 1 will be studying programming a due date. And we'll just use today's date for right now. We'll clean that up later on. And for the task type for this one will just be dot coding because that's the type that corresponds with this task. And I'm gonna copy this and paste this Ah, every two more times and we're gonna change up the task in there. So for the next one will just do doing laundry and we'll change the type two dot house work . And for the final one, Uh, well, dio planning trip to where we want to go. Um, Spain? How about spin playing trip to Spain and for the type heared will do vacation planning. So we've gone ahead and built up our data source and now the next thing we need to do is implement two of the methods here that let us add the data source to the table view and then for every row bind our data source items to every table view cell. So if we go down here to the bottom of our class, we're gonna start taping number of rows in section and you see that that's gonna kind of auto complete out for us. And let's take a look at what's going on in this ah function Signature were provided a table view and were provided a section. And what we need to return back is how many roses belong in this section of the table view and what simply we're gonna provide is returning the data source stock count, which means hate. There's three items in our list. Our table view is gonna contain three rows. That's exactly what this method here, it says. And this is something that the table of you has to have in order to know how much data it contains. So that's easy. We can simply return the count, and that's all we need to do for a very simple table of you. The next method we need to implement is sell for row at index path, and what this method does is it returns a table of you sell for every row of data that is contained in our data source array. So the actual method here, as I start to type, is self for row index path and returns. You I table of you sell. So if you could enter, they'll stuff about the function for us and then we can begin working on that. So, looking at the method signature, we have a table of you. We have a index path and we have to return a table view cell. And so what will end up doing here is doing Let's table view a cell equals the table view passed into us dot de que reusable cell with identifier. And I'll explain what this means in the second so for index path and will use the index path parameter here that was passed in. And you'll see here that when we look at table view so it's a type, and that type is you. I table view cell, which is the base class for a table you sell. And so what we'll do here is we're gonna return the table you sell, but we need to understand what exactly a U I table view cell is in. The easiest way is always starting by going into the apple documentation. So if we select you I table view cell and we commands click. It had jumped to definition. We're now inside of the U I Kit documentation for the class you want table you sell, and if we look here, we can see it derives from you, I view which we haven't really talked about too much yet, but it's the base level view for most every type of you I control. And as we look down here, we can see a couple of properties of interest. There's an image. You there is a text label. There's a detailed text label, and there's content view, background view and a few other things here. So the important bits, for our intents and purposes will be the text label, potentially the detail, text label and potentially the image view. So right away we're going to use the text label property to actually bind it the title of our task to. So let's go back and start implementing that right now and so we need to do here is as we just saw a table of you sell or you I table view Cell contains a title label or a text label. And if we want to sign the text, we need to do that on a particular task. So what do we know? Right now? We have an index path, and luckily, an index path contains a row, and every row corresponds to ah section in our array. So the simplest way to do this would be to say, data source at the index path Don't row and what we need to bind. Well, if we look here, we need to bind our title. The problem is, we defined our title as private so we can't access it outside of this class. And so what we can do is simply remove private for title, which makes it of type, internal and fertile means that the property can be used by the entire module, Uh, or basically the entire out, um, and private means It can only be used by the contents inside of the class. We always want to default to private because it's good practice toe Onley expose properties to other classes that need to be exposed. We don't want to expose everything because it always opens up opportunities for other programmers to make mistakes. When they start using our code if we give them access to every property or method of our class that they might not need access to. So that's why we defaulted to private until we needed to make something a little bit less restored, less restrictive. So now that this is an internal access type, if we go back here, we can then do data source at index path dot ro dot title. Before we run everything, let's ah, take a look at the cell here that signifies our identifier. If we go back to the story board, let's bring that up here and let's do the assistant editor and keep our to do list of you controller on the right hand side here. And let's go ahead and select the to do list for your controller table view controller and look for the table view cell. Make sure you have it selected and go to the address inspector here and you'll see that there's this section here for re use. Identify air here. I'm going to use the same name that I used in the code, which will just be sell very generic name and let's take a quick look into that method here . And since we have the options command, click into this deaky reusable cell with identifier. Let's do that and read the documentation and see exactly what's going on here. So it says right away that the newer it's a new ridicu method that guarantees they sell, was returned and recites properly. Assuming the identifier is registered now, there's also another one above it. There it turns an optional you I table view cell that's used by the delegate to acquire an already allocated cell in lieu of allocating a new one. For essentially, by trying to reuse one that's in memory and, if it's not available, creating a new one, um, in that instance. But we're using this method here. Reason the one that does not return an optional And basically what that saying is if we have more types of cells, we're gonna associate those with different identifiers so I might have a cell for maybe, um, you know, a feed table view cell. I might have one for a comment or, you know, like a ah, an advertising table view cell. And that might give each one of those different identifiers and I can't give them all the same identified because they need something that uniquely says This one is a particular type of cell versus the other one so that I can de que the right one. So that's why we want to set that identifier here and also in the storyboard for the type of cell for the identifier here and make sure that they match. Now, let's go ahead and run our project in see what everything looks like up to this point and it looks like everything's working. I can have three. I have three items in my table view my, uh, three tasks that I defined here in the data source, and sure enough, that all show up just fine in our table view.
7. Connecting The Detail View Controller: so our to do list table is working just fine. But we want to be able to pass that data along to our detailed view here. And maybe we want to show more information or have a different layout for every task in our list. So right now we have no way of getting from our list to our detailed view just right now. So what we'll do is go ahead and hook up the logic to moved to the detail screen when we select a particular row in our to do list. And the easiest way to do this is to go back to the concept of Segways. Oh, are creating a Segway transition upon selection from our list view to the detailed view, it's pretty straightforward. What we can do is if we go back on a select our to do list table view controller, we go back into the document outline here, we want to get a hold of the cell. So with having the self selected, we could do something similar. Where we hold down the control key, we click and drag over to the detail view controller and for the type of Segway we're gonna use a show. And here you'll see right away that we inherit the navigation bar from the navigation controller that encapsulate SAR to do this view controller, which has a back button to get back and that connection has been established. But there's still one thing we need to dio. We need to be able to send the data or basically our task, the selected test from here to here. And right now, even with the Segway said, we have no way of doing that. And that's something we're gonna have to implement this in code. So we're gonna need to do this in two places. Let's start first with the detail view controller. So we're gonna go into the detail of you Controller Swift file, and we're gonna dio is create a property. We'll just call this Laura Task Type task, and it's gonna be an optional. And what we'll do is imputed load, which will get called right When we enter this do controller, we'll just print out print tasker. We'll unwrap it just to be safe. If let task equals task print task DOT Title and we'll do next is go back to our to do list table view controller and, uh, well, go ahead and implement a new method that we haven't seen yet, which is called Prepare for Segway. And this is a method that we're going to override. If you select the method here, let me see if I can pull it the documentation. Uh, it might not say anything right away, but let me see if we can jump to the definition here. Looks like I can't see it, but this gets called right when the Segway is about to occur. And so this is the point in time where if we want to pass data around to the next few controller that we're going to, we have the opportunity to do so here. If you look at the parameters to this method, you have the actual Segway, which is a US storyboard Segway. And then you have the sender, or basically what sent the call? What was the element that was tapped that invoked this whole chain of operations for us? It's going to be the you a table for you sell because that's gonna be what the user has selected. That started the transition for the Segway. And that's why it's type can be any, because any possible type could be something that triggered this. So we have to cast it, especially when we know that we're expecting that a table of you shot cells was gonna have been selected that we can unwrap and get ourselves and then get the index path from ourselves and they get the data for that particular road and then send that over the destination do controller. Now, the Segway has also also has a property Segway destination. And you could see here that is a type. You have you controller. And this is where we're going. In our case, this would be detailed view controller, and so that's how we'll pass the data. So what will ultimately do here is will do this with you things. Um, if let selected cell equals sender as you I table view cell. And actually, no, we'll go. Believes a guards statement here because if we can't get this, we don't care about doing anything else. You will simply return. So we're gonna guard and we're gonna let are selected. Selby, the center as a US able of you sell if we can't get it, we've bailout assuming we did get it, but we can Then do is let selected index path equals table view, and we're using the table view property for the table of you controller dot index path for cell. And so we'll do is pass in the selected cell. And this methods basically ah, method available on the table view to get an index path. It's kind of a convenience method. There's a few other ones here to index path for row at a particular point index path for a cell provided a particular cell and index paths for Rose in a Tennessee directed in the notice here that these return optionals. So we have to also check to make sure that we're getting back about index path here. Or we could have a runtime crash if we force unwrap something with a no value. So we'll also do another guard. Let check here guard, Let selected index path don't return. And assuming all of that worked, we'll do one more check here, and that's going to be, um, all right, let destination do you control a diesel view controller equals segway dot destination you controller as the type of detail, view controller and I'm actually gonna use an if let here. Um still, I guess it won't really matter, but well, we can do either or else turn at this point assuming everything worked out, Do you tell you, Controller darks Task equals. So now we need to figure out, OK, we have the selected index path and the selected index path has a property on it called Roe and that actually gives us the row in basically our array for where the item exists. That if you remember here, that's exactly what we did to bind our title to a cell. We did exactly the same thing. We use the data source at the index path dot wrote to get that item, and we're gonna do it the exact same thing right down here and prepare for Segway so we can assign the task for our guests are detailed view controller based on the selected index path, row for ourselves and that's it. So let's go ahead and build this and verify that we build and it needs to be the selected in its path that one more time and everything's good. And now one other thing we can do here, but before we run. This is, uh, a basic principle of debugging is, ah, concept of using break points. Sometimes if you want to step through your code to see if things are working or not working as expected, you can go over here on the side bar if you don't have your line numbers visible. What you can do is go into X code into preferences, and I believe it's under See here. Where is that? Under fonts and colors, text editing line numbers. So, under text editing online numbers, you can talk all that on and off to see the particular line number where you want a break point out. Once your line numbers were turned on, you can go over here on this column on the left side and click in a little place of break points. So once this loads, we can see the path of execution and test the things they're working as we expect them to. So now let's go ahead and run this in the simulator. I'm gonna go ahead and select studying programming. And so it looks like our Segway completed. Our detailed view controller just got invoked. You did load was called and now we're checking to make sure we're able to pass the task we unwrap succeeded. And sure enough, studying program is being printed out to the console. So we have successfully passed our task from our to do list to our detailed view controller .
8. 7. Subclassing UITableViewCell: so far is starting to come together. But we still need to do a few more things to make it look pretty and understand some more common elements for user interface development in IOS. But to get us started, we want to go back to the topic of sub classing. So obviously we subclass Tara detailed view controller here. If you remember, by assigning his class to detail view controller, and we can do that with many, many, many elements in Iowa's especially classes from you like it and the next class, we want a subclass that will allow us to do more. Customization is on our actual table view cell. So if we go over here and we expand our to do list table of your controller and ex elected cell and we go over to the glass inspector here, you can see that right now the classes just you I table of you sell it hasn't been assigned . It hasn't been sub classed. There's no way we can really tweak or add. Testing is ations to this cell, and that's actually something that we want to do right now. So what we'll do is go back over to where our source code is in the project folder or right click, and we're going to create a new file, and we're gonna call this our to do table view self. Actually, we'll do task table view so a little bit more concise, don't click, create, and we'll go ahead and import and the necessary You like it, which contains the table view cell. And then we'll define our class class task table view cell, which derives from you I table view cell and we'll go ahead and get that set up just like that for right now. And what we'll do here is go back over to our storyboard. And now that we have created a task table view cell, we can then subclass ourselves in the actual storyboard file. So if we have ourselves selected and we go back over to the class here, we can do task table view cell and had entered there to make sure it gets out. And that subclass has just been defined. And one other thing we can do what were in here. As we start to add in more swift files, we want to try to keep our project kind of nice and organized. So what I'm gonna do is start creating folders and if you right click your project folder here for the name of your Projects folder and go to new group. But you can do is start creating folders to put these pieces of source code. And so weaken Dio, for example, of you controllers. And we can take our detailed view controller and by shift, pulling the shift key and Clicking Week and then select both the detail and the to do list table you controller. And we can then dragged them into that view Controllers folder and that will move them right into the right place there. And we'll also do here is we'll do another one for a table staple of yourselves. So the table few cells and we'll take ourselves we just created it will drag that into the table of yourselves folder just like that, and I will do one thing for models or our data models. So being two models and we can take her our task and we can put that in there, and then we can just kind of have a general folder for utilities or just, uh, kind of places where we don't really have anything well defined, but it's used in other places such as our tasks height. So I was gonna create a folder called Utility. You know, just put the task type in there. And so it looks like we've got everything organized here for the most part, with our source code. You can also right click on the folder and dio sort by name if you prefer alphabetical, and I'll kind of give everything a nice alphabetical sorting out your project structure. Next, we want to focus on styling, are Tasked Cell. And if you go back into the interview list, table view controller and you remember that right here when we were actually Deke Ewing the cell on returning it. We're assigning this text label property right here, which is binding the text. But if you go back and look at the story board, it's not really clear that anything's happening. You have to infer that's going on in the code and be kind of nice if we could visually represent everything from our storyboard here so that we don't have to dig through the code to see what's going on, and I can Just look at this until that. Okay, there's a label here. There's gonna be text bound on this cell. I can move it, position it, change the font, the color, everything so on and so forth. And so that's the next step we want to take. And so to do so is going to require a couple of steps. Um, if we notice here in our hierarchy of under table view in ourselves that we have this content view. So let's say, for example, I wanted to do something such as just changing the background color, that from white to something else, and I'll go ahead and change it to yellow eso right now you can see that that visually shows up in the content view of the cell. So if we if we run this in our simulator, we'll go ahead and see what looks like a yellow cell. And sure enough, we changed the color. Well, what if we want to change the height of the cell? What if we want the cell to be a little bit taller? So at first glance, we think we can simply just kind of drag this down and, you know, making taller. It seems like it works well. We'll go ahead and run in the simulator and Ah, and we'll see what happens in a moment here and look at that. It didn't make a change. So what's going on here? We need to diagnosis that. Ah, it seems like there's some other setting that's overriding the height for our cell, and that's something we need to change. To support the desired height from interface builder, go back into the to do list table view controller. And there's another method here that we're gonna need to use another method we will need to override. So if you remember, number of rows and section was what gives us back the amount of data in the table and self road index path gives us back an actual table view. Sell Well, it turns out there's another method. Height for row at index path that returns SCG float, and what we want to do is figure out where this is coming from and kind of understand what's going on with it. So if we actually commands click into the U I table view controller, we can see that there's these two protocols You I table view delegate And you I table view data source. Now, you aren't able to data sources where the number of rows in section and self road index path came from. However, you have a table view delegate contains other things related to the custom ization of our cell and height. Furrow is is one of the things. So if we start typing height for row at index path, you can see that right here. Uh, that's one of the methods that we can override. And there's a very long description received, liken show that here comes up. Sometimes it does, sometimes it doesn't. But we can see here that this is where that method is actually coming from. And it looks like it took me to the objective c version of this of this, uh, ap I off this framework, which is fine. But if you scroll through here, there's a lot of other methods that we can override in addition to just this. And so I mean, there's a lot of customization weaken dio on a table of you, but let's go back and and just to clarify one more time, because our table view controller conforms to these two protocols. It allows us to override certain methods to do customization in our own view controllers, which is exactly what we're doing in the to do list table view controller. So if we need to return a height for a sell, well, then we probably need to know what that height should be, What the numeric value should be that we returned back. So in one way, we can kind of do that and match with our visual expectation is if we go back in the storyboard here and we select that cell and we go over here to this icon that looks like a ruler the size inspector, um, it has a row height attributes here that we can set and drag up, up and down like that. So let's just say I want this road to be e don't know, 145 and height. So with that number, with that number set here, that's the number that we're gonna need to return back in height for road index path. So here we're just gonna return 1 45 Now, let's go ahead and run this and see what it looks like with that height and because I need I need to actually put the override key word here because we're overriding this method in our implementation. So let's run it. And so we have our height now, but you'll be like, Okay, well, why is it it's white stuff going on? What's what's all that about? And 11 other visual debugging trick we can use is there's an icon right here if you see where my mouse cursor is on X code. And if we if we click that it takes us into the view hierarchy of our app alive. And if we start clicking around here, we can see various elements of our structure. If we expand over here on the left, you can see that haters, our view controller. And if we go down, there's a table view and here's a cell, and then so on and so forth. And if we actually click, we can see that Oh, that's a you I table of you label right here. So it looks like the labels being stretched and that seems a little strange, right? So then we go back in our code, we figure out, OK, well, where we have signing that label. And why is it being stretched so tall? And we see right here that this is where we're actually assigning our text to the label. So let's just right commenting it out and run the AP one more time. So this will build it fresh and see what that changes. And so now, even though we're not binding the text, you don't see that white label anymore. It's gone because it's never being assigned. We're gonna end up doing is using our own label. We're not going to use the actual default label on the cell. And instead of returning just a you a table of you sell, we're going to return the task type cell or the custom cell that we created so that we can do customers Asians on it instead.
9. Introducing Auto Layout: So let's begin by adding our own labels to our sell well at a label for title. And I think Lata label for the type A swell to start off. So what we can do here is start going to go down to the object library here on the right side and start typing label. And, uh, we're gonna drag a label over onto our storyboard here, and, uh, we'll go ahead and get that set up and we'll dio is well dragged the corners here to increase the within the height. What kind of brings out to the edges? Those little dotted lines are kind of layout guides that tell you where you should kind of stop. Um, Dragon Beyonce because that would be outside of the, you know, the recommended guidelines for the user interface style guidelines it up for Apple provides . But what we can do here is trying to get this set up someone looking like this. And if you go to the attribute inspector, we could start changing font size and color positioning so I can change my positioning from left Justified Teoh in the center. I can also change my actual font if I wish to do so by default. It's assistant fun. But if you go under custom here, um, we can start picking around to do different things. I think I'll try a different phone toe. Let me see if there's anything in here I'd like to use. That looks good. Ah, dio. Actually, I think I'm gonna keep it and sell that it Can you now? I don't really see anything in there that interests me. I'll change it to Ah, bold. How about that? Um, that's fine. And I'll bump up the size just a little bit here, and I think that should be good for that one. Um, and we'll also do the same thing for the type, and we'll just go ahead and put that kind of right below. So we'll drag another label over. And actually, rather than dragging another label might be easier just to copy the one that we do have. Just do command, see? And if you kind of move your cursor anywhere on your cell and get commands V paste, we can paste the one we just copied. And if we want to change this to be, like, kind of a sub lit like a subtitle instead of a title, Um, we can just go. And instead of bold, make it Ah, let's see what light what it looks like. Yeah, I suppose I could work. Um, you get that set there and position it accordingly. So one thing we need just to talk about is what's known as auto layout. And it's basically a constraint based layout system that allows us to create adaptive user interfaces, interfaces that will respond to the changes, such as the device orientation or the actual device itself. You might be running on an IPHONE, SC, an iPhone seven plus and iPhone 10. There's lots of, or even an iPad. There's lots of different devices and screen sizes that we have to consider when we design our APS, and that's where auto layout comes into play here. So if we're going to understand anything about constraints, we need to understand how do we apply those constraints from the storyboard or from interface builder? And so you've probably seen me at some point doing some stuff here with maybe horizontally and vertically and container for centering things. But this is where we start to get into our constraints from in here. So if we select, for example, our title labeled and we go down to this little icon here for adding new constraints, we have options here, too. Basically constrained. Are you element or our label a certain amount of pixels or points away from the top? The left, the right in the bottom, These air, also known as the leading side in the trailing side, we have constraints to add a fixed with the fixed height aspect reissue. There's lots of things here that we can tinker with. And auto layout can be frustrating sometimes for new developers. It takes a little bit of time to master it and to kind of understand how to add constraints that don't conflict with constraints and other elements. So a handy thing that Apple added is over on this icon here. There is a way to resolve on a layout issues, and it usually gives you a way to set suggested constraints so you can have it kind of automatically set things for you, Um, that you might not have been able to figure out on your own. And when auto let selections were made. If you go over here, and you go into your your table. If you sell your content view, you'll see now that you have a little section in here called constraints, I need to expand that you can actually see each individual constraints in the collection of constraints. You know, you have the trailing, the top, the leading and, uh, you know you can You can inspect all the values that show up in the attribute Inspector here didn't even make modifications to them if you want to. But what we want to do is keep it very basic. So what we'll do for ours is we're gonna add ours manually. We're not gonna do the Apple preferred way. So we're gonna select our first label. We're gonna go down here, and what we're gonna do is apply a top constraint, a left or a leading constraint, a trailing constraint or a right constraint and a height of 44 and add four constraints. And so now, basically were saying that if our cell expands in height, are labels basically gonna stay fixed and pinned to the top of this cell, It's not really gonna go anywhere Now we're gonna go ahead and apply similar logic to our subtitle label below. We're going to select it, you know, back down over here, and we're gonna add our constraints. So instead of doing a top, I think we're gonna try to pin this one to the bottom of the cell so we'll do a bottom constraint of zero trailing or right constraint of zero in the leading or left constraint of zero in a hide constraint of 44. So that's gonna fix that height and kind of pin that sell to the bottom. And so, so far, so good. Um, ourselves, we're looking pretty good. Now let's go ahead and run this and see how it looks visually in our table of you on. One thing we'll need to do here is just make sure that you've commented out where you assign your text here. Otherwise, this is gonna override anything. We did an interface builder, So let's go ahead and run this in the simulator and C without setting the text. This is what we kind of have. We have our title label here and are a subtitle label below and positions just how we set them in Interface builder. And so I have decided. Well, you know, I see I kind of put my label to the bottom here, but I think it look a little bit better if I moved it up just a little bit more. And so we can do that quite easily. If we go back over here to that little ruler icon for the size inspector and click it, what we can do is adjust the Y axis a little bit by moving it down. It actually brings our label up. So if we start to click down, I think mine was at 90. If let's say bring it up to Lake 75 my men might look a little bit better. You'll see I'm getting all this orange stuff in here. And this is basically apple saying to me that, Hey, you got a problem here? You said some constraints that said that this thing gets to be the Y axis of 90. You just moved into 75. What's going on? So give you some options, you can update the constraints, which means that your constraints, instead of expecting to be at 90 will be a 75 which will resolve that issue. You can update the frame of your label to match the constraints. Now, if we did that are constraints are at 90. Well, we just move everything to 75. If we update the frame to match the constraint, it'll actually move. Are labeled back down to 90 s. We don't want that where we can let Apple re calculate the constraints entirely on do it for us. And so we don't really want to do that because that kind of defeats the whole purpose of what we did. Eso Another option to is you can make those changes here a swell so time to go back down to the result bottle a issues you have also that options, you update the constraint, Constance. That's really what we want. Because if we do that, it just basically tells that constraint to hey, expect this thing to be at 75 not at 90 and then you'll see that that warning just went away. And now let's run this and see what it looks like. And so that looks a little bit better. Um, good enough for for what we want to do right now. Another thing you might realize is like there's a divider line here. That kind of looks do it now that we have started to change some of the styling and it be nice if we could turn that off and it turns out that we can, it's actually a property of the table view. So if we go back to the storyboard and we select the table view over here and then go to the attribute inspector here, there's a property called separator that it said to a default value. Eso What we can do is we can turn that from default to none if we choose to do so. And if we run that right now, let's see what that looks like. So you see now that that that separator is completely gone, um, let's say we want to add our own, um, separator, maybe a little bit thicker that looks a little bit larger. We could do that to and again. It's another opportunity to practice using a lot of layout. So instead of a label, what we're gonna do here is look for you, have you and it's just a plain view like this. We're gonna drag this over into the content view of ourselves and we're just gonna try and get it here. And what we're gonna do is make this really small dragged on. I think a height of ah, maybe eight will be good for now and of resume in a little bit cause I'm sitting in my track pad. I'm going to drag the edges of this view all the way to the edge of this time not to the recommended guidelines to kind of create our own little divider bar. And what I'll do here is not a position that right I'm gonna go at some constraints to it, to pin it to the bottom and fix that height so similarly So what we did to that subtitle label. I'm gonna do a constraint of zero at the bottom constraint of zero for the right or the trailing in a constraint of zero for the left or the leading and a height of eight. It's about doing that love that fixed right where we want it. And I'm also gonna change the color of this view to something other than white. So if I get to the absolute inspector here, I think black would probably look pretty good. Here s so we can get it looking like that. So now let's run this one more time and see what that looks like visually in our simulator . And so maybe that bar is a little bit too thick, so that's fine. We can simply go and adjust it just like we did in update our constraints along the way. So again, another opportunity to practice on the layout. We can drop that tight down from maybe seven Teoh from eight to Maybe before would look a little bit better. And you'll notice here that my little divider views moved up as I have decreased the height . So we're gonna want toe if we if we if we decrease the height by four, we wouldn't push it down by four on the Y axis. So you can do that from here if you want to. Or you can simply just trying to drag it down to the bottom like this, Um, and you can get it right on the edge there, and you'll still have that orange because you just you just made changes to the frame without updating the constraints. So we just have to go back and do it. We did before for resolving on related issues. And we'll update the constraint Constance to match the frame that we just adjusted at and let's see how that looks now. And I bet that look a little bit better and what we had before and, yeah, I think that's good enough to work with. We might be able to go a little bit thinner, but it's not the end of the world.
10. Pulling in Task Table View Cell: So now we have our cell designed, but we still need to fully replace you. I table view cell in self road index path to use our task table of you sell. And so we need to do that right now. So let's go back to the table view controller Need to do less to tip of you controller. And we want to go back itself. Road index path here. And so right away. Um, you know, if you start typing table of you sell, uh, you'll notice that the type is you. I table yourself on That's not gonna work for using a customs up class, uh, that we created, which is the task table you sell. So it's really not an issue of what we can do here is, since our task table view cell is a table of you sell, we can just cast it as a task table. You sell, and we'll do. Here is since that's gonna be an optional Well, just make a check. So if let table view sell people's our test table yourself else, we'll we'll do something different. What we can do here is to find a bar. Uh, cell equals you have a table of yourself so you can start off with a new instance of a cell . And if we can actually eliminate or else statement here and if we get our table view, sell here the type of cell, it's going to be a task table yourself. Um, so what we'll do here is for the technically return, we're going to return the cell, and then we're going to say that ourselves. Eyes are table, you sell so we'll do it assignment there. We'll delete this here and now. We're basically saying that we're gonna we're gonna build a new cell because we can't return back until sell it asked in return a value. If we're able to dick, you are cell as a task table of you. So then go ahead and assign that sell back here and return it. But there's still one thing we're missing. We need to configure the cell so that it can bind the data model to the actual view to actually put the labels for the task title and the task category. We haven't written any code to do that yet. Eso what weaken dio is if we go to our task table of you sell. Um, we haven't implemented anything here, but we'll create a new function. So phone configure with task and the parameters goes in the A task, which is the data model. And we need to go ahead and create interface builder outlets that let us connect our labels back to the class here so that we can do the bindings when we receive a configure with the task. So we'll do here is open the assistant editor. So I thought that open over here and it looks like I've got that stretched out too far from you to see if I could collapse that a little bit sliding server. And I'm gonna bring up my storyboard on one of the 10 pains here. And so if we go into these cell and we expand the content view, we can see that we have these two labels the title and it's entitled Now, since we sub classed this cell is tasked table view cell. We have a direct connection back to the source code file so I can create interface builder outlets right back to the code. So they hold down the control key and then click and drag over to the cell inside of the class. And I release I can cook up a new connection here of type outlet. And since I selected the first label, I was gonna call this task title the label and connected. And I'm gonna also do the same thing for the some title right below it Gonna go hold down the control key. Click and drag over here. It was called This task. So title like that and then let's go ahead. And when we get a task to configure our table view cell, you can simply dio do task title That text equals task the title. And so we have one little problem here. If you start typing task dot only the title is exposed. And if you remember why, we're only showing just the title. Originally when we used the table of yourself. So not a problem we need to do is go back here and expose something else from private to internal so that we can access it outside of the class are the task class. So to do that, simply do this. We can just remove private from the type and just have let so its internal, which is the amount of Maine internal. It's really this, um internal is the actors as Thea access type. However, if you don't specify anything internal is the default so private is explicit. Internal is implicit unless you make it explicit by typing internal. So just something to remember. So let's go back now. We combined up our task. Subtitle So task subtitle text equals task dot And if you can't see the type, do command be to build the project so the pilot could pick up the change. We just made the access modifier and then you should see the type show up here in this list . Um, so right away, we're gonna have a little bit of a problem here. The problem is because we cannot make the assignment because task type is not a strength. It's just literally in the name of a task, type its own type. So there's a couple of ways we can work around. This probably the easiest, is going to be just converting this to its string with the indium. So if you go into your task type, what we can do here is say that this is going to be a string and weaken. We can make a kind of ah string readable value for each one of these cases so we can instead of studying all lower case, we can say studying like this, we can do a default value here for else work. No, we can do coating like this. Weaken dio Vacation planning's like that. So it's a little bit more human readable when we bind it to any kind of you element. So going back here, um, that because it's a string type now we can do is we combined to the Taif and we combined to the raw value, which is the actual string itself. You might need to do command be to build a project here eso that it compiles successfully. But see, once I start typing it again after compiling, I have a raw value, which is a string that shows up. So, um, what we can probably do here is change because we don't we want indicate that type just a little bit more readable so we can do something like this. Weaken dio tape, and then we can inject in our little task type like this got tape, stock value So it's going to run this in the simulator, it see what it looks like. But actually, before we can do that, I almost forgot. We actually need to do the configuration here. So the final step is going to be close. Our assistant editor here, table of you sell thought figure with task, and, uh, that task is going to be something we need to get back in the data source. So what we do here is just let ah, let's ask equals data source at the index path dot ro. And if you remember, I was kind of just passing in this way before, But I'm just explicitly getting the task just to show you that you can also do it like this If you want to be a little more explicit, um, and then passing the task like that to do the configuration. So now let's run it. And we should have all of our bindings hooked up with the new addition of our subtitle bound up to our label. And sure enough, you can see that studying programming site coding, doing laundry type house work and planning trip to Spain of type vacation planning. Everything seems to be working
11. Building the Task Creator View Controller: now, at this point in the tutorial, we've definitely made a lot of progress on our table view list. But the problem we have right now is we only have three items that are basically hard coded . We have no way of dynamically adding new tasks to our list, and that's something we're going to fix in this part of the tutorial eso. What we can do here is that we have a navigation bar. Uh, we can add a plus button to the top right here. And basically, when we click that plus button, it's going to load another view controller. That's going to allow us to input a new to do list task into the form, and then we can save it and loaded right into our our to do list automatically. And so the first place to get started is back in our storyboard. So what we'll do here is we're going to go back and go down to the object library here. It's not typing bar button item, and this is a type of button that we can add to a navigation bar or a toolbar, and we can just drag it up here to the top left of the top right, and that will give us a nice button that we can use from here. And once we have our button selected, you'll notice that it shows up under the navigation item, right bar button items and then the actual item here. And so if we go over to the attribute inspector, we can change certain attributes to our our button. For example. Maybe instead of this custom selection style, we want to do an ad which would change that icon to a plus icon, which is kind of makes sense for what we're trying to do. We can also change the attempt from the default blue to maybe something that looks more fitting for our theme, which is yellow and black. So I could do something like like that as well. And once we've done that, what we want to do now is hook up the interface builder action for when this button is tapped or clicked. So if we go back and open up the assistant editor and we put our storyboard on one side and our to do list table view controller on the other side, we can go ahead and and create that action. So if we kind of go down into our code here, you just pick a arbitrary place and we select our button. If we hold down the control key, we can click and then drag over to our file and from the connection type from outlet. We'll change that to action, and we'll just call this create, ah, new task tapped and connect it. And so really, at this point is where we're going to. Instead, she ate the new view controller that we need to create by presenting it totally. And once that's presented, well, input a new task into that view controller save it and then automatically reload. That day, that mu task into our list. Now we're ready to create our view controller. So go back down to the object library here. We're gonna drag a new view controller onto the storyboard canvas, and this is going to be our task creator view controller. Um, what I'm gonna do here is I'm going to just style it yellow and kind of the same theme that we've been following for the app. You can choose whatever background color you want to use, so I'm just gonna leave it like that for right now. And what I need to do next is actually create the source code file for this view controller and similarly, just like we did with the other two will start by creating a new swift file. And we'll call this one task creator view controller. Well, then go ahead and import in your kit, which contains the you have you controller class. And we'll just define our new class as class Task creator. Few controller of tired drives from you. I view controller and will override the view that load as our entry point into this view controller eso. Then once we've done that, um, if you have your assistant editor open here, we can go back and hook up, uh, the source code file so that it maps to the new controller and interface builder. So if we selected in your view, controller, we just created we go to the class inspector here, we can go ahead and to find that as a task creator of you controller and we'll just go ahead. And also is that the storyboard i d and the restoration idea in case we need to do anything programmatically later on. And really, what weaken Dio is from here are new plus button. We can go ahead and do a present Mota Lee option right here to actually sure Newtown's creator view controller, uh, when we put that button. So let's go ahead and test that in the simulator real fast and see what that looks like. And so my simulators open here and I hit my plus button and there we go. So my test creator view controller loads. However, right now, we have no way to dismiss this because we have no back button or any kind of safe button. So that's the next thing we need to implement is the user interface for the task creator view controller.
12. Task Creator View Controller User Interface: So the next thing we need to do is design the user interface for a test creator view controller. Before we could do that, we need to kind of see what elements we need to add that are required to create a task. So if we go back over to the task dot swift in our models folder and we look at our task class, we can see that we've added three things. We have a title, we have a due date and when we have a task type. So let's start off with the easiest one which will be the title. And what we can do for that is dragged over a text field. So if you go down to the storyboard and in the bottom corner here for the object library, if you type in text field, drag over one text field onto the storyboard, and this is going to be our input field for our task title, so what we can do here is start to kind of position this, um, where we wanted to go. I'm just gonna kind of get it here for right now. And the next thing will do is go back and hook up the interface builder outlet for our our text field here in our view controller. So go back over to the task creator of you controller and right above you did load what Weaken Dio is create that connection. So, holding down the control key, we can click and drag over into the view controller, and we just call this task title text field. Next, we'll go ahead and add two more text fields, So let's go ahead and drag on two more. So dragon One here and another one here and was going drag those out. So they're all the same with do the same again for the 3rd 1 And the next thing we need is a button to actually invoke the process for creating a task. So if we start typing for button, we'll drag on the actual button that comes up here not the bar button, but item, but just a button. So we drag that over onto the storyboard, and we can do here is instead of the text button. We can go to the attribute inspector and type in, um, create task, and you can drag the ah within height over to get a larger button there, and I'm gonna change the color of my text color to black. I could stick with the theme of our app. And I'm also gonna change that text font here from from custom, I think I'm gonna try something different. Um, so Helvetica new is the type there, but I'm going to see about Ah, but I have installed here Traven here and then we'll do Ah, maybe a bold thought here. Heavier font if we can. Well, it larger And just for that increased font size off drag that a little bit more. So now we have most of our input controls created. The next thing we can add to kind of give this of you control a little bit more polished is a name like basically a title in a way to get out of it. Because we have no way to dismiss this view controller right now. So probably the easiest way here would be adding a navigation bar. And now you'll notice here. When I started having a navigation, you'll see navigation controller and navigation bar. The main difference is if you remember in the previous tutorials, is the navigation controller is a special form of a view controller that provides you with the navigation bar. However, this is a view controller that we are presenting Motive Lee. We are not and had been betting this in a navigation controller per se. So when we actually trade a motile Segway like we did here, which has the plus button that takes the Segway all the way to hear you remember that it comes up from the bottom. It's not pushed onto the stack the way any other view controller inside of a navigation controller is done. But we can still kind of simulate the same kind of look with the navigation bar. So if we just dragon navigation bar onto our view controller, what we can do here is, ah, start to create something that kind of still look similar. But it behaves in a mobile presentation. So with the navigation bar dragged over here on the top, well, we can. Then do is add in a button to dismiss this. So if we start typing for button and misspelled, but in their duties, we'll drag over a bar but an item onto the left side of this navigation bar and what we can do here is if you select your navigation bar and you go over and open that little side menu on the bottom here, if you actually take a look at the view hierarchy for the control Navigation bar has a title, a left bar, but an item here with an actual item inside of it. So that actually is this item, and it has the ability to also add a right bar. But night, um, if we were to just drag over another item here, we could effectively create another button. But we really don't need one for this one. We just need a way to get out of it by dismissing it. So the left one here is good enough for now. So what we can do is start by changing the title. If you select the title here and you go to the attribute inspector, it has a default text set the title so we can just call this new task or create new task. Let's see how it looks. So that looks OK. Um and then if we want to also change the text for the actual button, if we go down to left Barbara items and then select the actual item, which it is the button. We can go here and change some of the attributes in the attribute inspector, so you'll see here. It pre loads it with the item text under the title. We can just change the text too close, for example, and you'll see that it updates it right here. Another thing we can do is change the tent. There's blue is the default tents, but if we want to keep our theme and change it to the black text color that works to, there's a few other options here. I believe there is a done option, which these are just some of the default ones Apple provides. Um, cancel, undo. Save some of these you can use out of the box if you want to. I'm gonna undo that just cause I want to use close also to there are different styles you can use border versus plane. Uh, they don't really show too much visual change in the storyboard, but there's just a few different options here that you can you can change so and now that we have most of our form filled out way, we need to start getting everything in the proper position. Specifically, we want to try to keep these control elements fixed someone in the center of the of the form, but we need to do it a little bit more elegantly. The reason we need to care about our layout is if you select your view controller and you go down to the bottom here where it says view as and you start picking different device sizes. For example, I'm on the iPhone eight. But if I clicked on, let's just say the iPhone S c and you go back, you can see that now all of my elements are not centered. Same thing here. If I go down to the four s, it looks even worse if I go up to the iPhone 10 here. It also looks kind of bad. Um, and on the iPad, it will be really that eso That's kind of our problem we want to solve is how do we build an interface that looks pretty good across our device sizes, and that's where auto layout comes in. And specifically we can use what's called a stack of you, which manages a lot of the vertical or horizontal stacking of elements that are laid out in a similar fashion. Kind of like this, and it enables us to not have to implement the constraints. Suman meticulously an interface builder. It kind of manages some of the auto layout for us or makes it a little bit easier on DSO. That's what we're going to do next is create our stack view to basically encapsulate these elements and vertically positioned them. It was honestly center them in this view controller. So what we need to do is select all of our control elements at the same time. One thing you can do is drag a box around them like this, or you can pull down the shift key and click each one individually with ships key held down . And it's like them all at same time and what we need to do. Before we had the stack view, as we want to say that we want to use to be the same with on high it that they are right now, we don't want those to change, so we can do here is go down to this button and add in a with it ahead constraint, which adds it for every single control that selected in this group. Now you notice everything's in red here because we have basically constraints configured that are not enough information for auto layout to know where to position these things. So that's why it's giving us errors or constraint errors. That's fine. We'll fix that as we go along. So now that are within height for each one is fixed. We can embed them in a stack view by pressing this button here, and you'll notice that they're all smushed together. There's no more vertical spacing between them and ah, with with and the height is still remains unchanged, which is what we want. So now I can drag around the stack for you. And if you look here inside of the task creator view controller, they expand the view hierarchy. You can see that as you go down, you have your navigation bar and I understand you. And if you expand it, you see, all of our elements are added on the inside of it. So what? We can do it here, So actually select our stack for you and kind of position in the center here and what we can then do is go over to the attribute inspector here and start looking at some of the properties for our stack view, and you can see that there's an axis which is automatically put it vertical because it's detected that there is an alignment. And we can increase the vertical spacing by pressing this spacing button up or down to create a vertical space between her elements. Equally where you know you can change the distribution and alignment options from these drop downs in here. But you'll notice here that there's still a bunch of red ah in our, um, constraint guides, and you'll see that we're missing constraints for a few different things. Exposition of why position is unknown for all of the task title text fields because in reality, the only constraints that they have on them or the within the height ones that we added. We haven't added any constraints to our stack few yet, so that's what we need to do right now. And the easiest way for us to censor everything here is to horizontally and vertically center the stack new. So if you select your stack view from here, which highlights it here and you go down to this button here for the Align. What we'll do is select the horizontally in container and vertically in container and add this constraints and you'll see here that it kind of positions Those moves him up a little bit and what we can do here is try to drag this out. So that is the true center of this screen here. And it looks like I have a little too much vertical space between my element. So I'm gonna decrease that slightly over in the attribute inspector here, try to get that look a little cleaner. You know, I think about twenties 20. Should be good. Um, so let's just, you know, make sure that's nice and center there, and let's see here if we have any more from straight warnings S o. This is just saying that the fixed with constraints on the button may cause clipping issues . Eso we can change this here or it may be unnecessary so we can remove that constraint in just because you notice here that the button is now exactly the with of the text in it with just the height constraint here, Um, and if we look back at our warnings, they're all gone. So we've result all of our auto layout constraint problems that we had also to We need to fix the navigation bar to the top of the view controller because it is no constraints added to it. So it just like the navigation bar here in the hierarchy This one's a little bit easier We can do is go down to, uh, the constraints button here for new constraints. And we'll just pin this one to the top, to the left or the leading in the right side or the trailing edges and add the history constraints right there and that will lock that in place. So now, with if we go and start viewing it on different device sizes, you can see that if I select the iPhone for us, we look OK. If we go look on the iPhone S e looks OK, and let's just verify things on the iPhone. 10 are looking good here, too. Looks OK. Let's look for the eight. Let's even take a look at tonight that, and to see what that lay it would look like on the iPad. And so everything centered and that's exactly what we want
13. Configuring the IBOutlets and IBActions for the Task Creator View Controller: now that we have everything laid out in positioned, we want to go ahead and start connecting, are you elements and is implementing the actual dismissal of this view controller when the close button is tapped. So what we can do is go over to the task of you controller here, and we'll keep everything side by side with storyboard on one side and the code on the other, and we'll start hooking up our controls. So if we go into the controller here, this stack, that task creators from you controller, let's start with the close button so we can go ahead and have that selected here. And we can create that. I be action by adding the holding the control key and then clicking and dragging over. And I'm gonna put mine right under viewed load. But from the outlet will change the type for the connection to action. And we'll just call this close button tapped. And while we're at it, let's go ahead and start adding in the other ones, too. We'll start with the title text field, so we'll do the same thing. Wilken hold down the control key and then drag over and create a connection for, um title text field. We'll do the same thing for everyone below task type text field and for the final text. Field will also do the same approach due date text field, and then finally will create the additional action here for creating the task so well. Control, key and holding, click and drag over. And since this is a button, we're gonna change the connection type from outlet to action, and we'll just call this create task kept now, as far as implementing the code here, probably the easiest piece to implement. Just we contest that everything is working is the actual close button being tapped itself. Eso What we can do here is when the close button is tapped to actually close out of the view controller or to dismiss it. It's simply this line of code called dismiss. So on the close button tap method Will will type into Smith's and you'll see here that the description says dismisses the view controller that was presented Motor Lee by the View controller. So the one that would have presented this was its do list table view Controller on bat's gonna be dismissed once we tap this button here. So all set animated true. And there's a completion handler for when dismissing is done that basically it's a call back saying that it's completed that its missile. But we're not gonna be doing anything there so we can pass in nil, since that's an optional parameter. And now let's go ahead and actually run this in the simulator and see what it looks like. I'm just gonna switch over to my iPhone at sea and start that up here and let's see what we got. So my simulators open now, and I'm going to go ahead and hit the plus button to create a new task. And you can see here that my, uh, menu comes up and, ah, if I have my clothes But in here dismisses the view controller going back up, Um, it comes right back. So now that we can dismiss are presented task creator view controller, the next thing we're gonna want to do is start configuring the text fields. Eso starting off with the title text field. We want to make sure that when we actually click into or tap the text field that we're able to bring up the simulated keyboard or the software keyboard and then be able to type in some texts, hit the return key and then successfully dismissed the keyboard eso to get started with that, What we'll do here is inside a task Creator view controller will create a new function down here and we'll call this private funk configure text fields. And when viewed load is called well, actually call this method to start configuring our text fields. And what we're gonna have to do here is configure the text field delegate. So if you remember the table view controller, uh, for our to do list table view controller, let's go back and take a quick look at something in there. We're gonna get in, revisit the concept of delegates and delegation. Onda actually manually implements a delegate in just a moment here. So if we go back here and we click into the U I table view controller, you'll remember that we had au I table view delegate. Now we didn't have to do anything because table view controller automatically implements this for us. But it's a protocol, and similarly, if you click into a command clicking into you, I text field and jumping to the definition here. Um, it also has a delegate. So if we search for delegate, there is a you I text field delegate. And if we take a look at what's defined in this protocol, it has all of the methods that are going to be called a notified for when different things with the text field happened, such as when the editing begins, the editing ends, the return key was pressed, and this gives us all of the firing points to do certain things that we need to do with our keyboard and dismissing it and what not? Um and so how we actually go ahead and implement the delegate is quite simple. We'll do is go back to our task creator of you controller here and inside of our configure text fields method. We'll start with the title text field, and it has the dot delegate property and will say that the delegate for this text field is going to be equal to self and self simply means task creator view controller. That's the class were inside. So what we're really saying is that our test creator view controller is going to be the delegate for anything for the U I text fields in this class. So any time things change, uh, text field interactions occur those tasks or those notifications or, um, callbacks will be relayed over to the task creator view controller who is the acting delegate. And so the way will actually implement the methods here because you can see that I'm already getting an error That says I cannot assign this value yet is because task creator view controller has to conform to the protocol. You I textual delegate. And so what we can do is create an extension on task creator view controller That conforms to the protocol. You I text field delegate and assumes I do this. You're going to see that that error is going to go away now. Why did I do this in the extension? Well, I could have also easily have just done it up here. I could have done you I textual delegate, but has good practice, especially for swift. It's very common to wrap your protocol, conformance or implementations inside of an extension on whatever you're working in to kind of keep the responsibilities separate so I can handle all of the U I text field delegate methods inside of this extension. That's separate from all the corelogic going on here in the view controller, kind of keeping them isolated and just keeping things modular. And you know, this a separation of concerns just is a good practice for a swift, swift programming, and I a less so Now we have to figure out what methods in here do we need to implement? Because again, if we go back and take a look at the text field delegate, pretty much everything in here is optional. Which means we don't have to implement these weaken just conform to the protocol like I did and do nothing if we wanted to. But even though that's pointless, we have the option to implement any of these or none of them, depending on what we're trying to do. So the obvious one that we absolutely need is Text Field should return, and we're gonna return true here and analyze what this method does and why we need it on DSO. What's happening here is that Miss even put the documentation by selecting this method, and if I go over to the right side here, sometimes it doesn't show it right away and ex code. But see if I can jump to the definition of it here, Um, see here jump Teoh. So it says that it's called when the return key is pressed. Return no to ignore it, and it provides the text field that was interacted with. So if I clicked on the title text field and hit the return key, this text field would technically be the title text field. Same thing for the due date. Same thing for the task type text field. And so if I want to dismiss that keyboard, all I will do is say on this text field provided from this delegate method. Resign the first responder, and that's basically saying that resign the element that's in focus right now and dismiss it, which at that point would be the keyboard. And the documentation can probably explain it better than I can, where it says that it notifies this object that has been asked to relinquish its status as first responder in its window on DSO. Now, if we go ahead and run this in a simulator, let's see what this is gonna look like. So my simulators open here I'm going to go into the task creator view controller, and I need to make sure that my keyboard has turned on here because, um, okay, looks like it is. But now if I press the return key, see how it's dismissing it? So I click in keyboard comes up return key to do business. Now if I try the same thing for the other two text fields, see, it's not it's not dismissing. The reason it's not dismissing is I've only had designed the delegate for this one, which means that the callback to dismiss her return that you're basically dismissed. The keyboard will not fire for the other two text fields until I also assigned the delegate the same way I did the title text field. And so that's something we still need to do here in one other thing, too. If you don't see on the simulator your keyboard coming up because this this is a setting, you have to turn on going to hardware, look for keyboard and make sure you had toggle software keyboard like mine was working, but it should have been ah, we go back there and make sure that, um right, Okay, you'll go ahead and said that to make sure that you can toggle it. Now let's go ahead and do the same thing for the other two text fields and assign their delegates so we can go right back into that configure method here and go due date. Text field delegate equals self and task type text field, not delegate equals self. Now let's go ahead and run in the simulator one more time and see if we could dismiss the keyboards for all three of these text fields now. So going into the create new task view controller, if I go down to the other text field here and hit the return key, you can see that it dismisses. It's no. If I go down here into the 3rd 1 hit the return key, you could see that it dismisses as well. So all of these air now working properly due to hooking up the delegates for each one of them. Now let's take a look at some of the attributes of a you a text field, so go back over to the task creator of you controller and select one your text fields and go over to the absolute inspector here. And let's take a look at some of the properties that we have available. So in addition to text, color and font, we can also change, like the position of the text left aligned center Landry the lion justified. So we probably want our text to be centered just because it just visually is going to look more appealing. Um, and there's also this option here for placeholder text. Now, placeholder text is basically a prompt to died the user to let them know what kind of text or what information that should be putting into the field. So ah, good placeholder example here would be Enter Task title and usually this used to show open interface builder. I don't know why it's not anymore. Ah, we'll see it when we run it. But this used to also show up here as well back in the older versions of X good, um and ah, let's hear going back to that 1st 1 here. You can also change the border style if you want to, so you have a clear border kind of a rectangular border with a black outline, recessed border. That kind of looks like it's recessed inwards, and then the default one, which is the rounded one that we've already been using. There's lots of other properties here as well. Another interesting one is the keyboard type, the default keyboards. What you saw, where we had the letters and numbers. But you can also change it to be just a number pad or a phone pad. Um, s so that's one way you can set it from inside of interface Builder. Here s a lot. Lots of options, especially the return key. You can change the return key to something else such is done or next, or any of these options available instead of just returned. And there's also a keyboard. Look, there's a dark one, a light one. So, um, let's try. Let's change ours. Too dark just to kind of see what that looks like. Um, also two. We probably want to set the other two text fields to have the same kind of style so ominous that the keyboard look too dark for the, um, middle one and the keyboard. Look for dark for the 3rd 1 Also to have an ad, the placeholder text for this one. So I think we'll probably dio task type here. So for the placeholder text will do enter task tape and for the 3rd 1 here will do Enter task due date And now let's go ahead and run this in the simulator and see what it looks like. So simulators open here and ah, I've got my task title here And that's what the dark ah, keyboard. And it looks like I forgot to center the text on the second and 3rd 1 but no worries. Weaken. Do that real quickly. You notice here that's the dark themed keyboard, and you'll see here the placeholder text. And as I start to enter text like a new task, the placeholder text goes away. If I remove my text, the placeholder text comes back. Uh, and I'll just fix my others. You text fields real fast by dis entering their alignment. And now that look just like the 1st 1
14. Introducing the UIPickerView: So now we need to finish gathering the input from the user from our text fields and then creating a new task in dismissing the view controller and for selecting items from a list. IOS doesn't really have the concept of a drop down menu like you've probably seen in Web APS or even an android app. What we have instead is the you I picker view, and that allows a user to make a selection in a scroll herbal list rather than having to input data from scratch like they would. Any white text field and the due date text field in this house type text field are going to need you. I pick reviews for selection, so let's take a look at the U I text field. In more depth, go ahead and commands. Click into the text field to jump to definition and look for input view on the U I text field class. And this is going to be the view that's presented when the text field is tapped or comes into focus in the responders chain. And essentially, it's going to bring up a U I picker view that we're gonna configure with our task types or due dates. And then once a user makes a selection, will remember what they selected. And that's going to be the data that goes into creating the new task. So let's go back into our view controller for the task creator and start getting this set up. So the first thing we're gonna do is start by creating a new property, and we're gonna call this private bar due date or a tasks type picture of you. It's gonna be a type you I picker view. We'll go ahead and declare that optional because we need to configure it first. So what we'll do here is inside of the configure text field methods, uh, are in for your text fields. Not that we'll go ahead and set that up so we'll do task type picker View equals you. I have a picture of you to create a new instance of it and what we're gonna do next. Since we're going to start with the task type, the task type text field in front of you is going to equal the task type picker view. And now let's ah commands Click on you. I pick, review and hit jump to definition and take a look at this class and see what it is. So right away we can see here looking at the inheritance chain that you I pick review derives from a u I view. And that's the reason we were able to assign it as the input of you because ultimately it inherits all of the you. I've used properties and in the inheritance chain here. Now, for the I pick review itself, it has its own components and customize ations here and really two important things to take notice of our the delegate in the data source. That's like we did with the U I text field delegate. We're going to implement the delegate in the data source manually in our task creator view controller eso Let's go ahead and start working on that now. Um, so we've already gone ahead and assigns the input view here, but the next thing we need to do is configure the delegate in the data source. So what we'll do is a task type text field. I'm sorry. Task type picker view Start delegate equal self and task type picker view data source Equal , self, and we're going to get a compilation air pretty quickly here because we haven't conformed task creator of you controller to these protocols on, just like we did here at the U. S. X field delegate. We're gonna do the exact same thing for the picker view, so we'll go ahead and create another extension here. Extension on task Creator. You can shoulder it's gonna conform to two things is gonna conform to the U I. Picker view data source in the U I picker view delegate protocols and, ah, the mandatory one we have to implement is the data source. And so let's go ahead and commands. Click on it, jump the definition and see what we need to do it in this in this one. See here you I picker view data source Sometimes X code, uh, breaks when you commands click into things. So e found the protocol here, and the two things that we have to implement that are non optional are the number of rows and the component and the number of components. And so that's pretty basic, right? Uh, even here, if you're not sure what a component is, it's basically a column of scalable data, and we'll see pretty quickly once we get this hooked up so we can start with that right now . So let's start typing number of rows component, and we'll just return zero for the moment and a number of components, which for right now we're just going to turn one now, So so far, so good That will get us past the compile error that we would have had right here. But we still need to go ahead and actually build up the array or the data source that's going to be fed for fed into basically this picture of you. And so if we go back up here, uh, since these are all task types, what we can do is create a private array. So private, let's task types, you know, we just have these being types string actually know what we'll do. Task type? Well, buying the string value. Um, and this is going to equal task or dot coding Got vacation planning dot studying in that house work for all the different task types that we support. And so now this is gonna be our data source that contains four items where the four different tasks available for us and it's we'll do here is go back down into the number of rows and we're going to return the data source or the task type tapes that count. And so right away here that's saying that we should have four items are picture of you because there's four items in the actual data source itself. Now that the data sources hooked up, let's actually explore the you. I picture of you delegate and see what's in here. So if we command click on it and jumped a definition when we search for you, I picked her view delegate. We can find the protocol here, and we'll notice that a lot of things here kind of related to the could the visual configuration of the control such as the with for a component, the row height for the component, the title for the row, uh, the view for the row. And then if you actually made a selection on a row, all of those air available here. So the ones that we're gonna need our did select row and title for road. We're gonna implement those methods right now. So let's go back to our view controller here and start working on the so we've handled this particle. Now we're about to start handling this protocol. So if you start typing title for row, you'll get back the title for road component method. Here, Noser returns an optional strength. Additionally, if you start typing in, did select, you'll get back. He did select row and Component, and we're going to also implement that. So we know when a selection has been made and get the item selected from the user. So what we need to do here is what are we given? Were given a pic of you were given the actual row and were given the actual component, which in our case, there's only one component for right now. So really, all we need is the row to figure out what they selected. So we can say that let selected task equals the task types at the selected row. And then what? Weaken Dio is return Selected task and I spelled that wrong. Fix that selected task return selected task dot raw value or the string value of R E newme for the task. And now we have everything hooked up to actually see what this will look like. Let's go ahead and run this in the simulator and take a quick look at what we have so far. So back in the task creator view controller here. If I go ahead and select the task type by clicking into it, you'll see Here's a picture of you. So now we have the actual selectable tasks that we can scroll through, such as housework, studying, vacation planning and coding. Uh, and however, there's no way to dismiss this right now. Our pickup. He's kind of stuck because if you remember with the text fields, we could just simply hit the return key to dismiss them with our pick of you. At least at the moment, we have no way of getting out of it because it's not playing by the same rules that the text field delegate was doing in the text field should return method here, but no worries. There's really two ways we can handle that quite easily. And if we go back to the did select road method here, one thing we can say is once they've made a selection, we can go ahead and dismiss that picture of you. But you might be wondering how would we do that on the view? There is a view, not end editing method. And if we go ahead and take a look at the documentation for this by command clicking and jumping to definition, it's used to make the view or any sub view that is the first responder resigned. And that's important because any time these text fields show their keyboard where they show their input views like the picker view is doing, that is a first responding element, and it's responding to. It's the first thing to respond to user input in the chain from first responders, basically, and by forcing it to end or by calling viewed and editing set to true, it's gonna automatically dismiss it no matter what's what type is open at that point. And let's see if there's even Yeah, okay, so from the quick up option here, there's even some more documentation. This method looks at the current view and its abuse of some view hierarchy for the text field that is currently the first responder. If he finds one, it asks that text field to resign its first responder, and if the force perimeter set to true the text field is never even asked, is forced to resign. So now if we run this and before we run, it will do 11 other thing here is will bind the selected type to the task type text field. So what we can do here say task type text field dot text property equals the selected or the task types for the row. And we're gonna bind the rob value, which is this strength to the actual text property here. And so let's run this now in the simulator and take a quick look at what it's gonna dio. So here we go. I got to make a selection to studying and you see that once the selection is made, it shows up here in the text field in the pick of you is dismissed automatically. And if I switch it again to house work, same thing back to coding selected and dismissed
15. Constructing the UIDatePicker: Now we're ready to gather the last piece of information from the user, and that's the due date for the task. So, like we did with the US, a picture of you were going to use a U I date picker, which looks like a you I picker view. But a lot of the logic in terms of the delegate and the protocol is handled by Iowa's for us. So what will start off doing is adding a private bar of do date picker and the type will be you, I date picker. And the way we're going to configure this is very similar to how we did the task type. So if we go down into the configure text fields method, we can go ahead and start setting that up. So we can say that the due date picker equals a new instance of a U I date picker. And then what we'll do here is actually take a look at this class and see what's inside of it. So command flick and then jump to definition of you. I date picker and we can see right away that from this class it inherits from you I control and and s coding. And you I control is another intermediary glass Between you, I view And you, I date picker that has more control or related properties. So if we go back one level here into the u I date picker, we noticed that some of the properties we have our date picker mood Ah, locale calendar time zone the date Ah, in a few different things regarding minimum date maximum date setting the date, etcetera. You'll notice there is no delegate or ah, data source that we have to implement here. And as I said in the beginning, IOS pretty much handles this for us. Eso It's kind of an easy to use a picture of you for dates Now there's also the date picker mode. You have time date eight and time and countdown timer. We're gonna use date for ours. So what we'll do is go back and on our date due date picker, do you do date picker don't date picker mode equals dot date And once we got now we're going to go to our text field, which is the due date text field and what we're gonna do to sign the input view equal to the due date picker. And again the reason this works is because, as you just saw, the input view is your view. The due date picker inherits from you I control which inherits from you, I view. Therefore, we can assign it directly to ah view no, no questions asked. So at that point, uh, there's still a little bit more we need to do regarding, um, actually handling the selection. So one more thing I want to take a look at is inside of you. I control This also allows us to basically add events. So just like we, um, handled button clicks and the storyboard dry be actions. We can also add button click handlers problematically, and that's done through add target. And so, since we're in Stan Shading is controlled programmatically, we have to make sure that we hook up the selected value changed or the handler programmatically as well. Three. Add target, which comes from you. I control and unsurprisingly, you I button also derives from you. I control, which is how it's capable of getting the button clicks through the at target as well. So let's go back and see what this is gonna look like back and task Creator view controller . We'll need to do here is due date picker go up the line here. Due date picker God had target and the target is going to be self self. Is these House Creator view controller. So we're adding this target to this class, and this is going to be an action or a selector. And the format for this is gonna is gonna look like this hashtag selector and the name of the class, which, in this case is tasked creator, view controller, and then we need to give it a method that's gonna be invoked. So I haven't created that method yet, but we're going to do well. Call it. We're going to call this new method date selected. You know, we just call it, um, date here and for the u I control events. We're going to use thought value changed. And if we take a look at this but committed clicking on the value changed here, if I could get in there, we'll go back to that one's this compiled because we still need to add that method. So the method we need to add is funk date selected date you I d picker. Well, actually call this just to be clear Date, picker date. But you're here, okay? And we're going to need to do one more thing so that this works ready to add at O B J c here and let me see what this air says. So right, here s their first instance Method date selected that is not exposed to objective C ad at O B J C. To expose this instance method to objective C. So if we hit, fix automatically What you're gonna see here is it's gonna, uh, put at O V J c in front of the method here and you'll see that that warning goes away. So I'm gonna command to be and build real quick and verify that everything compiles. And I wanted to take a look here at this value changed and let's see if I can find that easily here, Um, search for value changed right here. So there's different kinds of ew events in the U. S. Control events struck here. We are interested in listening to any time the value changes. Basically, when the user selects a different date, this event is going to get called, but there's other things to there's touch. Cancel touch up outside touch up inside, which is commonly used for you. I buttons, touch, drag lots of different things here that you're gonna want to take a look at and see what might make sense for what you're trying to dio if you're doing programmatic Uh uh, selectors the way we just did. So let's go back. And now that we have all that hooked up, but we can do here is print out date picker got date and let's go ahead and run this real fast in the simulator and verify that everything is working as expected. All right, so let's go ahead and quit this and see if our control comes up and it does. You can see that it has three components. It has a month. It has a day and it has a year. So if we select, let's say April now you'll notice that that date selected method that we added programmatically through this ad target method here was just invoked because the value changed event was fired. So now if we print out the date picker dot date right here, let's see what we got and it looks like for 18 2018 now, that's okay. I don't really want to use that format unnecessarily. So what we can do is use a date for matter to format the date that comes back into a format that looks a little bit prettier. And then we combined that to the text field. So for formatting, the date, the format that I think will be the easiest to use here will be this kind of format capital . Mm, dd Why? Why? Why? Why? So that's going to stand for the month, the day and then the 44 number year. And so the way we conform at the date that comes back is by using a date for matter. So we'll just do flett Date for matter equals date before matter. And then we'll set the format to that string. I just typed in the comment. So date for matter dot eight format that equals No, just just use this exactly as it is because it's the right format that string there. And then what we'll do is let formatted date equals date for matter dot string from day and the date that's gonna come back is from the date picker here. So it's basically passing back itself in the in the method here because it was changed. So date picker. Not that one. No, no, no. No date picker dot date. And so at this point, what we're gonna do is actually bind that string value to the due date text field. So due date, text field got text equals formatted date. And what we'll do is after after we've bound it to the text field will dismiss the input views. Will do view got end. Editing is set to true, just like we did for selecting a task. Now, let's run this in the simulator on, see what it looks like. All right, So go into the, uh, due date text field here, and let's go ahead and pick different date. I'm gonna try June 18th and look at that. So eyes your six for the month 18 for the date or the day and then 2018 for the year. Let's try picking something else will try. Maybe September 18th. Let's maybe bump up the year 2020. Maybe bump up the date. Few days. 22. It looks like everything's working there. If you go back and try the other field here, um, that's working as expected as well. Uh, make sure my simulated keyboards working here, software keyboard and, um, trip. And sure enough, everything is working just fine.
16. Improving the User Experience: now, before we're ready to create the task, there's a couple of things that we want to improve upon. You notice right away that are titled Enclosed Button are really close to the status bar here, to the point where it looks visually unappealing. So that's something that we definitely want to address. And in addition to that, uh, what if a user accidentally opens up a, um, picker view a keyboard or a date picker, but doesn't want to make a selection from there and has no way to dismiss the actual field ? There's no close button. There's no way to get out of it without actually making a selection in the actual picture of you. And that's something we also want to improve on as well. So let's start with the navigation bar and see what we can do there. So the default space were generally the the heights of the status bars 2020 pixels. So what we would do is take our navigation bar that we have right now and scoot it down by 20 pixels there. So if we go back over into the main story board here, we can start working on that right now. And if we go into the task creator view controller and we go down here to the result auto layout issues, we can select me clear constraints while we have the navigation bar selected so that it will only remove the constraints for the navigation bar. And once we've done that, were free to start moving the navigation bar around. And what I'm going to do here is go over into this little ruler icon up top here for the size inspector, and I'm gonna start moving. The Y axis is as you increase the y axis, it will actually move down the control or the element that you have manipulated. So we want to move that down by 20. And once we have that there at ah, like was 20. But we can do is go ahead and add some constraints back to fix it in this position on the easiest way to do that would be going into the utterly out button here, and we'll add a top constraint, a right or trailing constraint, a left or leading constraint and ah, let's do a height of 44 there and ah, we'll get that fixed into position So now let's run this in the simulator and see what it looks like as it's so. It definitely looks better, but we can actually improve on this and take it one step further. We can actually replicate the exact navigation bar that a navigation controller uses by default inside of our model view controller that does not present inside of navigation stack. And to do that, we need to actually use the navigation bar delegate are a navigation bar and use one of the delegate methods to achieve that look. So what Weaken Dio is open up the assistant editor here. So we have our storyboard open and our code on one side. And if we go to our task creator view controller, what we'll do is select the navigation bar and create a Navy outlet to it. So hold on the control key, click and drag over into the view controller, and we'll just call this navigation bar can create the connection. And then what we'll do here is since we're going to actually use the delegate by assigning it, and if you did, lead will do navigation bar dot Delegate, which is a U. N. Navigation bar delegate equals self. Now you'll notice we're going to get a compilation error here pretty quick because test creator view controller does not conform to this protocol yet because we just added it. So exactly the same way we have done it for the picker view and the text field delegate. We're gonna do it for the navigation bar delegate. So we'll do that by creating an extension. You are tasked Creator View controller, which conforms to you, I navigation bar delegate and the method we wanna we wanna use from here. If you start typing the word position four bar which returns the, um, bar position, we're going to return top attached. Now, let's run that again in the simulator and see if that made any kind of improvement towards how our navigation bar was positioned. So you concede that the navigation bar here is now attached to the top very similarly to how it be navigation controllers. Navigation bar is eso. It kind of looks like it's still in the same style, even though it's a motive. We presented view controller, so it kind of works out, and it looks a lot better than what we had before now for dismissing any of the keyboard types that get presented. It would be great if we had a way to detect if User had tapped outside of the keyboard. And in fact, there is a way to do that. And we can use what's called a U I tap gesture. Recognize er to detect a tap on a particular you have elements in this case, we would want to put that tap on the view controllers view to determine when it was tapped and then dismiss anything that might be open. So what we can do here is create a new method. Um, private funk configure, tap gesture, Recognize er and we can call that in view. Did load right after we call configure text fields. So configure tap gesture Recognize er and will create a new, uh, gesture. Recognize her like this. So let some tap gesture recognize er equals that you I tap gesture. Recognize er and the initialize will use Here is the target and the action, just like we did before For the U I date picker. We're gonna do the same thing again, programmatically uh, adding on basically a tap handler. Click Candler So the target in this case will be self for the actual task creator of you controller And the selector is gonna be the method that gets invoked when the tap is selected. Now, in this case, I haven't written that method yet, But I'll start by writing out selector. And it will be the task creator view controller, um dot did detect? Yeah, and then right here, all creative function. Uh, open it where we have the other one. Funk did detect tap and let's see if we get now is probably gonna complain. Here, let me see if Ah, not yet. We need to expose at o b j C. Because I said this method can actually be used in objective C the way it's being initialized in Swift. At least let me verify that That's there. So OK, did detect app is there. And, um, if we wanted to pass in the gesture, recognize? Er, um when one way we could do that is, um, recognize er like this. And then if we go down here, let's go ahead and make sure that builds and it does. So that's one thing you can do if you pass in that parameter. You're basically passing in, uh, the control that was interacted with in this case, the recognises. So if we need a particular properties on the recognize or we could pass it in like that or we could have just left it is an empty function. It didn't really matter in the case of the date selected when we needed the date picker to get Thea get the time or the date that was selected. Eso that's just 11 way of going about doing that. Eso we're not done here. We still need to actually add it. So view, which is the view Controllers of you don't add gesture Recognize er the tap gesture recognize er itself. So now we're listening for taps and on the actual detection of a tap we'll do here is called view Got end editing said that True, Let's go ahead and test that in the simulator and see how it plays out. All right, so inside of the create new task controller, Let's see here so we can bring up our picture of you. And if I tap outside the tap gestures detected and we dismiss the keyboard by calling end editing and let's try it on the due date. Weaken business from there. Let's try it on the keyboard for the title. When you dismiss it from there, let's try typing something here, dismissing. We can still make our regular selections because we normally would. Strapping a date, Maybe we close it again, but we didn't mean to open it, and we don't want to make a selection. So we just quick outside and that covers all of our use cases here. So at this point, our user experiences that much improved on, and we are ready to create the task and pass that back to the to do list table view controller and added to the list.
17. Creating the TODO Task: So now we're also and ready to actually create the task. Um, So what we want to do here is go down into the create task tapped method here, and this is where we're gonna take all of the input that the user has generated and create the task on dismissed this view controller automatically. So to start off, we want to do a couple of sanity checks. We want to make sure that we can get all of the attributes and we don't have any problems. So the first thing we want to check for is getting the task title that the user put in so we can do a check for task title. We'll do a let task title equals task, her title text field dot text and we can do here is guard. Let it ehlz return, and we'll just put print failed to get required attributes. So if we go ahead and if we remember it to create a new task, we have to give a title, a due date and an actual task type. So in addition to all of that, what we can also do is we need to check for those two other attributes that we need now, in addition to just the task title we need to check for the due date and the task type. But also just checking for new is not enough. Ah, user could also fail to add in any text, even though the text attribute might not be nil, There might not be any characters in the text field, so we need to expand our check to also consider that scenario. And we can do that quite easily by expanding our Guard statement with a task title that count greater than zero, which basically says that there has to be characters in this title text field here before we consider it Ballad on. And if you're not familiar with the Guard statement, it's basically like if something does not equal nil check, however it's can be used more explicitly because guard very much stands for hay. Something could go wrong here, pay attention and let's use a program or know that there are some cases you need to check for. And you know this case right here is basically equivalent to if, you know, title text field out text is not equal nil and task titled that count is greater than zero , except in a guard Let's style syntax so we can expand on this for the other fields in exactly the same way. And if we had a comma here before the else, we can also do this. Um, let task type. Text equals task type, text, field, text and task type. Text count is greater than zero in our final case for this check is going to be let due date. Text equals due date, text field dot text and due date text account created in zero. And that will cover us so that we make sure we have valid text for all of our fields rather than just printing if something goes wrong. Wouldn't it be nice if we get to see some kind of era banner or an alert? It's pretty easy to do so. And we can do that with what's called a U I alert controller, which displays basically a little pop up message with a title and some text and a button so we can configure a new function for that private funk display error and error title string error message strain, and we'll create a new instance of a you either. Troller. Let's Ah, error Alert Controller equals au high alert controller. And for the initial Isar will use the title of message in style. We'll pass in error, title era message and for the title of style. I mean, we'll use the alert. There's also an action sheet, but that's not relevant for this kind of error message. So that gets us configured for the title and the message. But we also need to add in the okay button where the button to dismiss the alert view or the alert controller. So we can do that by creating a u I alert action. So let's, um okay, action equals you. I alerts action for the initial Isar for the title style and Handler, and for the text was gonna put okay for the style. I'm gonna put, um, default. And for the handler, this is just, ah, the closure of the callback for when the button is clicked. If you need to do any logic, even though it's optional, I'm actually gonna implement it just so you can see what it looks like. So, Prince, the okay button handler was called. And once we've created that, we just have to add that to the alert controller. I thought ad action. Do you add the okay, action. And finally, we need to present the alert controller. Same way we would've model view controller. So we just call present error Alert Controller Animated True. Completion handler, Nil. We don't really care what happens and let's go ahead and run this, but let's run it with Bad in. But let's test the, uh the non happy bath. So we want any or all of our fields to be empty so that we can see our alert control are getting called. So I go here, just call, create task with nothing in it. You can see I get the message also to If you look down on the logs, you can see that the okay handler was called. So that means this is getting a call back. Uh, civil. So, for example, if I type in here and just that create hit, okay, we'll see this brake point gets hit because the ah handler closure is getting reached right here. So, um, so we know that that works. Um, and now we're good to proceed forward with, actually building out our task So now we have the title, the type and the due date text. Now we need to build the type and the date from From these so we need to do next. Is starting with the date will create a, um let date for matter Equals did before matter And let, um, it's due date equals date for matter start date from string, which the string will be due date text and you'll notice this returns and optional here. So we're also gonna need to do a check for that so we can do, guard, let dude it equals that else return. But before we return, we can also display another error. And this could be a scenario where the user changed the text in the text field, uh, to something else. And it's not a validate anymore. So we put, um, Invalid date. There was a problem with the date and ah, last check will need to do is for the task. So let's make sure that our let task equals task. I'm sorry. Task type equals task type from raw value of strength, and that string is going to be the task type text, and it also returns an optional, So we're also I need to check for that nos turn, and we'll just do the same thing here. Display another error if we had a problem in Balad task. Okay, there is a problem with the ask type, and if all of that succeeds, then we're good to go. So let me to task equals task for the test title up here, the due date from here and the task type from here. And at that point, we can call dismiss, which will take us back to the, um to do list table view controller. So we'll call animated True completion for no before we run that. Let's also make sure that we're checking for the date format that we set from down below. So if you remember back here for the month, month, day, day year, we want to use that same format. So we'll just copy this and in our check here, make sure that format is the same. Ah, and now let's go ahead and run this and play around and see if we can create a new task and verify that in valid cases are being protected against Right now, let's just say um, wash the car. Let's just say it's house work and let's say I need to do it by tomorrow. But let's say I change, uh, house work to a task type that doesn't exist, like the car work. And then I hit. Create task. You'll see that invalid task type came up because there was a problem with the task type. I couldn't They couldn't build a case for this because it's not one of our supported types , um, in the enumeration. So if we put that back to house work, make that Now let's say we break the date. Um, by putting in an invalid date in dismissing create, there was a problem with the date. Okay, cool. So that seems to be catching that. And let's say we have everything else, but for some reason, we just decided Teoh omit the title entirely. It create task, missing required attributes. So we're pretty well protected here on the things ago. A little bit strange. And now, uh, finally wash the car, which now this is our valid case. Let's go ahead and create it. And sure enough, we created the new task and we dismissed the view controller Now we have one problem. How do we get to the new task from where it was in the task creator of you controller, back to the to do list table view controller and more importantly, having it automatically added to the table view. That is something that we still are not able to do at this moment. And so that's something we're going to solve by implementing our own protocol. That's going to be our delegate, and our delegate is going to be notified for when a new task was created and be able to add that new task to our table view controller automatically.
18. Introduction to Protocols and Delegation: So in our last video, we were faced with the dilemma of how do we actually pass the new task back to our to do list table of you controller. And while there are a couple of ways to do this and not necessarily a particular red answer , this is a really good point to start talking about particles and the delegation design pattern. So let's get started by may be creating a quick example in a playground. Just we can illustrate the point in isolation and then take that concept and apply it to our app. In my swift playground here, I created a very basic class on, and this is a class just called pet with one property, a name, an initial Isar that assigns that name. And this pet could be anything. It could be a dog. A bird could be a cat. It could be something more exotic, maybe even a snake. So a protocol is basically a blueprint, a blueprint of functionality. So if we wanted to define a dog for behaviors that would belong with the dog, we could create a protocol called Dog. We could say that this protocol has a function park And maybe this particle has a particular breed for the dog. So maybe a bar, uh, breed of type string. And at a very basic level, this means that any class that conforms to the dog protocol must have a breed, and it must have the ability to bark. So let's say, for example, we make pet conform to dog so we can do that the following way. We could do it. The this style of syntax here. And when we make pet conform to dog, you'll see that we're getting an era right away that does not conform to this protocol dog . And if you click the error message, it asks if we want to add protocol stubs. And if we hit, fix what'll happen. Is X codes automatically going to add in breed for a property and a function called Bark? And it's doing that because it knows that this is what we defined in the protocol right here. And so we have to have this behaviour because the protocol demands that we dio so we could do something like print. For example, um name barked loudly. We can also inject in a breed here for the type of that that belongs with that dog so we could do self dot breed equals breed, and it kind of guarantees a way to make sure that this class is going toe have certain things that we specify here. So if we add in the missing parameter for the breed and let's say Fluffy is a pug now when I can do here is instead of that I can say pet, don't work instead and we'll see that Loving barked loudly and fluffy. It is a read or a pug that part loudly so that the problem a little bit more sense in context here. And so that's one way we can make a class conform to a protocol the other ways through extensions. So we've been doing this pretty much all along. Um, as you saw with the U I table view delegate and data source, the you I picker view delegate in data source. We were implementing all of those through extensions. So now that we kind of understand protocols, let's shift gears and talk about the delegation design powder. So in the simplest terms, delegation is basically a pattern where one objector, one thing can delegate responsibilities out to another entity, class or thing that will act on its behalf. Now it's best illustrated through an example, and I think it'll make pretty clear sense once I show you this piece of code here. So let's assume, for example, that we have a class called pet owner or baby. Let's call a dog owner, huh? Now it's do pet owner and let's create another political called dog Delegate. And let's say this protocol has one function. Dog did bark. And so our pet owner has a pet. And let's just say that our actual het here and in this case will just assume that it's Ah , dog, um, has a delegate. So let's do var delegate of type dog delegate as an optional just getting started out. And don't worry if this is a little confusing, all make sense once it's all put together. So our pet owner, let's just say he has a name, which is the type string. Let's say he has a pet and we'll initialize him with a name and actual pet. So far, so good. Um and so what we can do here is actually in Stanciute our owner. So let's let's do that here. We'll say that. Let cut owner equals pet owner. Her name will be Jim. And that will be the pet that we just created above, which is our pug. And we're going to change our pet name. Teoh. Just name. It's a bug. And so, So far so good. So we have that set up here. Now, you remember We set this delegate property here, and what we can say is that our pet owner is going to conform to dog delegate, which means pet owner is the delegate or acts on behalf of his pet, whereas Doc in this instance. So what we can do is create another extent we can create extension. And this is exactly the way we've been doing it for you. I pick of you delegate in data source, table view delegate in data source. So extension on pet owner, which conforms to dog delegate. And now, if we let to sit here, we're gonna get a compile error saying that Hey, we don't conform to the protocol. We have to implement the method dog did Mark. So we start typing dog didn't bark. Now our delegate is the pet owner. Can react and do something about that. Maybe he's notified that. Hey, I need to feed my dog anytime, the dog barks. So how do we invoke that? And for me here, well, we need actually a sign the delegates. So if our pet owner conforms to the protocol and what we can say, pet dot delegate equals self. And the reason we can say self is because self refers to because it's inside of the pet owner. Classy refers to pet owner. And because this extension of pet owner conforms to dog delegate, that's the reason we can assign it to self. Which means once we have set this property here, we are plugged into the delegate chain. We are listening for any notifications or any events that are dog might happen to emit. Now, to invoke this, we have to actually from the health class or the dog protocol. We have to go ahead and inform our delegate who, in this case, our delegate is pet owner. That something happened. So in this case, when bark is called after a prince statement, we can say delegate dot did her dog didn't bark and will happen here is after we've gone ahead and set our relationships here. If we say pug dot bark, let's watch the console logs down here. So we see here Fluffy is a pug that barked loudly, which is this print statement. I got fired and then the delegate gets notified. When that delegates notified whose pet owner it comes down here in that statement gets executed. I need to feed my dog. So now the pet owner is aware that something happened and the owner is to do something about it. And we can use this concept for exactly the same situation for our new task and informing our to do table view controller that there isn't your task and we need to do something about that so again to summarize that the reason we use protocols for delegates is because they are the blueprint that defined the behavior in this case, dog didn't bark must be implemented by any delegate that conforms to the dog delegate protocol. Now, for our app are our to do list. Table view controller is going to become the delegate for the task creator view controller . So any time we create a new task, our task creator is going to inform any delegates that it has that it has created a task. And our delegates in this case will just be the to do list. Table view controller is going to be notified that a new task was created. We can pass that new task as a parameter inside of the method and then add it to the table view while we do the dismissal of our actual to do list. Our task. Creator of you controller. So now, taking what we've learned here about verticals and delegates, let's go ahead and implement our own delegate and actually hook that up so we can add the new task to our table of you.
19. Creating Our Own Delegate: now, taking what we learned from the previous tutorial, we can make our own task Creator delegate. So go to the top of the task Creator view controller back in the main project that we were working in. We're gonna create a new protocol right above our class. That protocol is gonna be called task Creator, delegate. And for right now, we're just going to add one method. Funk did create new task and will provide the new task as the one of the parameters to the method signature. And we'll just call this task here. So that's all are particles gonna have? It's really simple. One method. Not a lot. Teoh. Yeah, Conformed to. So now, back in task Creator view controller, We need to create any property, the delegate property. So we're gonna do a var delegate of type task creator, delegate, and you're gonna want to make this optional on the reason being is because your task creator view controller might not have a delegate. Another class may not have assigned itself to be the delegate for this view controller. So we do not want to try to invoke a delegate that doesn't exist. So by making it optional if we invoke it and no one is subscribed to this delegate, we're not going to get a runtime crash. So now we need to figure out where do we actually make this delegate call or when do we notify whoever is listening on the other side that a new task has been created? Well, the logical place to do that would be inside of the create task tapped method here. Once we've actually gotten down to the new task creation. So right here before we make our dismissal, we can simply do this. Delegate stock did create new task and pass in the new task just like that. And again, while this is optional here, if no one has assigned themselves to be the delegate, then that's fine. This will just pass right over. We won't crash in our apple work as expected. So now let's go back into the to do list the table view controller and make sure that it becomes the delegate for the task creator. So in our to do list here, um, we probably want to dio is get rid of this static data source that we define it here because remember we were hard coating use, uh, at the moment. But we're going to make these dynamic now by creating our own so we can go ahead and comment out the construct a data source for now, or remove it whatever you choose to do. If you do command forward slash you could highlight a block here and commented out in one Go. I also want to comment out in view. Did load where we call it, and once we've done that, we need to do here is make this guy this to do list table view, controller class conform to that protocol. And so, just like we did in the previous tutorial, we can create an extension on a to do list table view controller. That conforms to the task creator, delegate. And you might want to do a command be to build your project here because sometimes Mexico has trouble finding that, and once it finds it, we're going to implement that one. Not that we created called did create new task. And so once that new task had been created, we're going to get notified right here about it, and then we can do something with it, which in our case here is adding this to our data source on and then reloading our table view. Um, but we're not done quite yet. We haven't made the assignment, basically assigning to do this table view controller to become the delegate. Now, if you remember how we got to the test creator, if we go back to the main story board when we actually hit the plus button Ah, in the table view controller that automatically segue weighed over into the create new task . So right here, when we press this we Segway here to here. Now, the good news is inside of our to do list. Table view controller are prepared for Segway. Method is going to be notified, right when that's about to happen and you can see exactly the same way we tried to figure out the Segways destination to figure out what do you control or we're going Teoh, We can use that same approach here and figure out if we're going to the task creator and if we are go ahead and assigned the delegates itself right before this method finishes. And that's exactly what we're going to dio. So prepare for Segway. We have to be mindful of where we put this piece of code. Because if we look at these guard, let's a lot of we're gonna be returning here if certain things don't occur. So, for example, if we are trying to expect a u I table view cell, for example, if we wanted to go to the detail of you but we didn't get it, then we returned. Same thing if we couldn't get an index path or a detailed view controller. So we don't really want to put our code below here because it's going to fail if we're not actually going. Teoh the detail view controller. Um, so if we put it above at the top, here is our first check. So what we can say is, if let the task creator view controller equals the Segway destination, which is that you have you controller, we can cast that as a task creator view controller. So if that if that if let check succeeds, then we can say simply, the task creator view controller, I thought delegate equals self and self being the to do list table you controller because we've conformed to that protocol right here and then what will happen in this case is it'll continue down through this guard, Let check and then return because it's not a table of you sell. So we're not gonna have any issues there. We fail to actually make the assignment, and then we can do. Here is when this gets notified. So weaken footprint statement in here. Print a new task detected. We can add it to our data source. So if you remember, here are data sources, an array of tasks, and we simply upended it. We hard coated it in the beginning of this tutorial, but now we can upend it right from here. So data source that append task. And if we call a table view reload data after we upended, it's going to automatically reload every row. So let's go ahead and test that in simulator and see what it looks like. Our at our empty to do list table view controller. We've removed the hard coded stuff in there. So if we go to the plus icon here to create a new task, we'll just call this, um, coding tutorial, and it looks like my my simulated keyboards not showing up. So what I can do here is going to hardware while I have the simulator selected on a keyboard and Tuggle the software keyboard. And once we get to the task type, I was gonna end select coding and I'll say that due date is tomorrow and a gnome and go ahead and create that task and look at that. So if you look down here in the log, the new task detected was called and we upended that task, which means this got called back and we re loaded the data for the table of you. And let's do one more and I'll even throw a break point in here so you can kind of see it step by step. So let's say we want to go in at a second task. So, um, let's just say Ah, cleaning or document since we have a house work type of task. So house work and we'll say that's gonna be do on the 22nd of merch it create and watch. So boom, our delegate, which is did to do list table view controller is notified right away. The new task has passed. We depend it. Reload the data and Walla Now We have two tasks. And if we wanted to go into the detail of you for one of them are old. Code still works exactly the same way we can. We can tap into each one of them. However, we haven't implemented this yet, so it's not gonna show anything. Um, but everything still works. And so now, um, now that we have that working dynamically, the next step in this tutorial will be implementing the detailed view controller for when we add a task, then make a selection on that task. We want to display that here and pretty up the user interface because it's pretty empty at the moment.
20. Styling the Detail View Controller: Now all that remains is to style the details view controller and to make it look pretty and show the data that we're passing over from the to do list table if you controller, which is the selected task. So if we go back over into our detailed view controller here, you'll see that all we have is the task that we pass over. And then we printed out inside of you did load. So we're gonna have to go back to our storyboard and start setting up some additional U elements to configure. If we go back to the storyboard and look at our detailed view controller here, it's pretty barren. So let's go ahead and start adding in some interface elements here. But we can do is go down to the object library in the bottom, right, and we can add some labels to start off with. So we look for you. I label we can drag one over onto the view controller here, and let's just try to increase the within the height and give this a good position. We can kind of start from the center of the view controller, then work out as we need to and what we can do here is center the text and, uh, we'll give this a little bit more space may be dragged to the edges. Just give it maximum room and these little blue dotted lines. Or lay out guidelines that tell you the safe areas where you can position you elements and let's go ahead and start off with this one for the title. What we'll do here is open the assistant editor. Yeah. I mean, just drag this on over, man will open up the diesel view controller on one side here. And so what we'll do is start creating some connections. So we'll connect over the label, and this one will serve as our title labels. So this is called this task title label. You connect it and let's go ahead and create a few more. So I'm what I'm gonna do here is copy this label. If you do command, see for copy or just simply select the label on do edit copy, you can achieve the same result, and command V the isn't Victor. We could paste it. There's two more. One for the type and one for the due date. And so Let's go ahead here and try to line them up. So let's go and move these up a little bit. And we can select all of the labels at once by just holding down the shift key, clicking each one at a time for multiple selection. And we can drag these up and try to get some kind of in the center like that. Now you'll notice here that I'm viewing this as an iPhone eight. Now we have to be careful here because our title could be long. It could be big, Um, and we have to make sure that this is going to look good on a smaller device screen size. So before we actually hook up any constraints, let's set some fonts for these labels. We'll start with the title and will select it. They go to the Attribute inspector here on the right side, and we'll change the font to something different. I'm gonna dio in avenue or fun, so I'm thinking Avenir next will change the style too bold, and let's make a kind of larger. So it stands out. Uh, think 32 is probably big enough and for the other to the type in the due dates. We'll go ahead and set those, um Teoh Avenir next, but a different we're not gonna use bold we're gonna use. I think medium will probably look OK and we'll go ahead and bump that up. I think Teoh 26 looks pretty good. We'll do the same thing for the due date, which is the third label here. So the avenue next medium size 26 and let's do that here. Okay, so that's looking pretty good so far. And so now that we have that, let's try and actually add the auto layout constraints to fix these into the appropriate positions. So if we start with our title label and we go ahead and select it, if we go down here, we can see that it's 146 away from the top 16 on from the left side and 16 from the right side and 37 down. So let's say we want to maintain a certain spacing between the labels below it. Obviously, we could use a stack view like we used before in the input creator view controller, but another Another thing we can do here is kind of move around our labels getting kind of close to each other. And we can then look as we make vertical changes that what was 37 has now become eight pixels or be or eight pixels away from from where the title label is. So if I want to move these down a little bit more, let's say, uh 123456789 10 and maintain a space of 18 away. I can do that here and also to If I select my task type label, I see that it also has its eight pixels away from the due date. So if I want to maintain that equal spacing, I can go ahead and select the due date. Increase the y axis more, which pushes it down. I could do that by a value of 10 and then I can go back and check the type could see that. Okay, it's at 17 so I need to bump this up one more, and I could maintain that spacing there of 18 between all of them. So once we've done that, what we can do is select each one of them again, and we can drag all of them together and really look for that center. The layout guide will show you where it ISS at this point. What we can then do is with all of them selected, we can have multiple constraints at the same time. So let's say we want to add a leading and the trailing constraint so that 16 away from each layout guideline, Let's go ahead and say We want to fix the height at 55 for each one of these. Let's go and add this to see what happens. So almost we're getting a problem here because there's still some information. Auto layout needs to understand where to position these. And if we look at the actual air measures that we're getting, we need a constraint for the Y position. So what we basically want to do is try to say, Hey, auto layout. We want a physician, every one of these labels, exactly where they are at their Y axis right here in this particular view controller. So if we go ahead and select all of them at the same time, and then we go down here to the button for a line, what we can do here is check off vertically in container, but don't go ahead and hit at just yet. You'll see here that the current value is set to zero Now, if it's set to zero, what'll happen is it's going to vertically position everything in the dead center because that's going to be the zero axis here for this view. Controller on. We don't want to do that because what will happen if I do it? We don't want that. That's undesirable. So I was gonna hit Command Z or just edit, um, undo And I'm gonna show you the what we need to add for it s So we really want to Dio is do what we did again, but good on here. Check off vertically. But go to this drop down and use the current canvas value. With that saying is, take the white position for every one of these you I labels and that's going to be where it's vertically positioned, then had add the three constraints and you can see that they stay where they are Now all our warnings go away because they're positioned correctly. Now here's the important day. So right now we're still doing this is an iPhone eight. Let's say we go down to the smallest device size, which is the iPhone four s, and let's then work. Look at our title and let's go to the actual inspector here and add one of our longer titles. And if you remember the default title for one, we had was planning a trip to Spain. Now, see, that's a problem. Um, our text is getting clipped because the thought is too large for the with of the device. Now, if we go back to an iPhone eight, it's not a problem. We have enough screen real estate to handle that now. Luckily, there's an easy solution for that, and what we can do here is if you have the label selected Weaken, go under to the auto shrink right here and see how it sets a fixed font size. We can change that to a minimum thought scale or a minimum font size, so I'm going to select minimum font size and you'll see here that it's set to a default value of 16 and all of a sudden our label now fits inside of an iPhone for s. Now, if we bump back up to a plus. It goes back to the higher font size to 32. And if it's just fine now, let's say we go up to an iPad and just take a look there and you could see that we're still using the maximum size we defined as 32. And we're dead center in the vertically on the screen where we wanted it. So we could even bump up that fun size a little bit more. Maybe, Ah, 35. And we'll jump back down to the iPhone for S and you can see that it still is scaling the thought appropriately for the device size, which is great. So now we're ready to hook up the last two labels for the task type in the due date and before we trade the outlets. One thing we need to make sure we do is go back into our task here. And if you remember, we initially had all of these start off this private private so that no other class could access them. That did not need access to these properties. Well, now we need access to them because we're binding them to the interface. So we need to do is change the due date from private to internal, so we can just delete private and internal is the default access modifier, and now we'll be able to access it to make that binding. So once you've done that, let's go back to the detailed view controller here and start creating our outlets for the other two labels. So I'm going Teoh, go ahead and just control. Click over and it's gonna be the task type label, and I'm also going to looks like I may have deleted that connection. Let me put this back to the test title here and then also do for the due date. And now we have all these connections in place. Let's go ahead and create a new function, private funk configure interface, and what we can do here is instead of this, if let task equals task, we'll just go ahead and cut that. For the moment. We're gonna call configure user interface on view. Did load inside of the method will paste that if let Jack here, and the reason we're doing that Jack is because task is optional. We want to make sure that we actually have a task before we start doing any kind of operations that could potentially be binding, no values and causing a run type crash. So now that we have, ah, you know, successfully tracked and unwrapped our task, let's go ahead and actually start hooking it up. So starting with the title, we could do task title level. Got text equals the task dot title. Similarly, we can do the task type label that text people's the task dot type dot for all value brought value because it's a e newme. That's a string type in the wrong values, the string representation of that enumeration. And finally, for the task due date label. We're going to use a date for matter because if you remember task dot I'll have to hit command to be here because we need to compile in that change we made for the date to be internal. So now if I do task dot you can see the due date comes up and it's a type date, so it's not a string value, so we have to convert it so we'll do a date for matter. Let date for matter equals a date for matter, and we'll set that date format a format to the same format that we used from the Input Task Creator and put few controller. So that was a capital M m lower case D D and lower case. Why? Why, Why, why? And then finally, what we can do here is the task. Due date label, not text equals the date for matter string from date. The day will pass in is the task dot due date. Now, before we run everything, let's fix one final thing. The notice here that the detail view controller and the storyboard has a blue back button, and it doesn't really fit with the theme of our black on yellow kind of style. Now, if you remember, uh, if you remember, this navigation bar is coming from the navigation controller because it's inherited because it's embedded in that hierarchy. So a quick fix for this is we can actually set a global tent on the navigation bar to actually be a different color. So if you go and select your navigation controller and you go into here and select the navigation bar we can do is go into the attribute inspector of the bar, go down under word, says view here. Look for tent intend to set to this blue right here is a default, but we can change that to a different color. We can change it to black, for example. And when we go ahead and run this, it's gonna be a black back button. Also before we run it. Let's test one more thing in the detail view controller. There's a property called Title and if you read here, it's a local s during that represents to the view this controller manages. If we set this, let's just dio task detail. Well, actually, seeing the navigation bar, the actual title show up here in the center so that we can give this Ah, little bit more of, ah, information as far as what screen we're on. And we want to make one final change. Go back to the to do list the table view controller and just so we can quickly test this out, we'll go ahead and un comment, deconstruct data source method just to put back the static tasks that we had created. And now let's go ahead and run this inn an iPhone SG, which is a smaller screen size just to verify that everything is looking and acting like we expected. Teoh. So let's go ahead and click on one of the longer ones like planning Trip to Span and you can see right here that are back Button is black. The task of detail title is showing up here in the center of our navigation bar, and we could see our text planning trip to Spain. It's looking good. It's not cropped off. Let's go to this one again. Looks pretty good. And now let's actually try creating one. So just call this, uh, new task and I was gonna do make sure my keyboard is toggled here. We'll put that into the study in category. Don't say that's due in a couple of days. I didn't create it. And so here is our new test that got put in at the bottom because we had our statically defined tasks loaded in here. If we go into that one new test task studying and that's the due date that we had set. So it looks like everything is working as expected,
21. Adding the Polishing Touches: now in the final phase of our tutorial, we want to make our up look a little bit better, particularly on our to do list table view controller. Specifically, we want to do three things. We want to add a title to the top of our navigation bar. We want to make these cells a little bit smaller vertically, and then when we have no cells in our table view or an empty list, we wanna have a background view that displays a label indicating that we need to add some data to our table. So let's get started first with the background of you on our table view, and what we're gonna do is we're going to create a label, but we're not going to create a label in the storyboard. We're going to do it programmatically. So the first thing we'll do is go to the to do list table of you controller and comment out our construct data source method here, and we'll go ahead and take a look at what we have right now when we have our data source comments it out, and so we just have a white view. We don't really have anything here that indicates that we have an empty lists. We just don't see anything. Show up. So now let's go ahead and take a look at a very interesting property on the U I table view . So what I'm gonna do here is just commands. Click on any of the U I table of use. I confined and jump to definition and inside of the table view. I'm looking for a property called background Byuk, and if we read the documentation here, it's an optional you have you and the background you will be automatically resized to track the size of the table view. This will be placed as a sub view of the table view behind all cells and headers and footers, and that's exactly what we're going to use. We're going to create a label programmatically, which derives from you, I view, and we're going to set that label as the background view for our table view. So let's go back into the new controller and start implementing that. Now Let's go ahead and implement a new function here so we'll go ahead and creating function called private funk display, empty table view message. I was actually just got displaying the table view will say the parameter is the message because that's a little bit more clear in our method naming here. So once we've done this, we're gonna pass on a message. We're going to create a label, and then we're going to set that to the table views, background view. So getting started will create a label like this. Let's empty, uh, let end info label equals au I label if you remember you, I label is what we would drag on from the storyboard onto one of our view controllers in interface Builder. So essentially all we're doing is creating one of these programmatically. And if you see here, this little box, the rectangle, the corners, this is what's known as the bounding box, also referred to as the bounce, um, or the frame. And so, essentially, that is what a label consists of, or any you I view like element. It is some sort of control with a position of a box. It x y coordinate within the height. And so when we create a label, if you see here, we have a few initialize er's we have a u I label just empty label Brett, And then we have one with a frame and one with a coder. So since we're not gonna be doing any kind of un archiving from data, we're not going to use the coder method. Normally, we could use the frame method. And when we say said a frame, we're really saying I want to set a X and A Y within height. So, for example, if I said I want this to be at 100 X, maybe 100 why and 200 within 50 and height, Well, I could equivalently go back into the storyboard, and I could take a look here, and I could actually set those around by manipulating the X and Y the within the height to see visually what that might look like. And I could do exactly the same thing in code by using the siege erect you. I label initialized with the frame right here, But the nice thing is, we don't even need to go through figuring out of frame because just like the documentation , said the background view of the table, you will automatically size the you live you or the label or the control to fit inside of the background view, so we can simply just create a U I label like this. Now let's go ahead and create the assignment so we'll do a table of you dot Background view equals the info level and right there we've gone ahead and done the assignment, but we're not done quite yet. We need to go ahead and set the text and configure our label. So what we can do here, next to set the text, think the label don't text equals the message. So right there. So far, so good. Now we need to set a few more things. We want to text to be centered. We don't want it to be left justified, a right justified. So what we can do here is look for info, label dot text alignment, and we can set that equal to the dot center. Additionally, we want to set the number of lines to zero because if we have a really long message, we want to not clip our label. Um, for one line, we wanted to spill over into multiple lines, so by setting it to zero, it'll allow for in just that situation for it as many lines as the messages long. Now let's go ahead and set the thought So we can do here is on info label. It has a property called font eso. It's au I font and we can create that programmatically Just like we would set an interface builder like this You I found we'll use the initial Isar name and size so we were using I think Helvetica new and I think on the bigger label on this table cells was bold so we could try that here and see what that looks like. It will said it may be to a size off 20. Just so it kind of is large and stands out. You know, that tick, uh, spelled that wrong? It looks right. Our function here looks pretty good, but we still need to figure out Where do we call this? Now, there's a couple of possibilities here, but a really interesting possibility, at least in this example, because we only have one section of our table view is in our number of rows and section. Um and so a section can constitute as, ah grouping of data and you can have more than one now if we had more than one section in our table view. We might have different kinds of data rather than just one array of a particular type. Now, what we need to be mindful of is we have to always check. Well, when do we want to display this table of you message? Well, really, we want to display it any time or table view is empty. How do we know if our table view is empty? Well, our data source will probably be zero for the count, and that's exactly what we can do. So if we go into number of rows in section here and say if data source that count equals zero or an empty table view, then go ahead and display the empty table view message. And what we can say is some to do tasks. And then else, assuming the data source that count is greater than zero in this instance, the table view background view we said to know so it won't have the label. It will know how it won't have a view associated with it. It'll actually render the data. So any time we add or remove elements and basically reload the data source. This method will get called and then we'll make the check here. And then if we have nothing in the table view, will display our message. If we have stuff, will remove our display message. Now let's go and test this out and see what it looks like. So here's what it looks like and it looks okay. We can do a little bit better because that bold really does kind of stand out. Um and ah, the boarding might not be the best. So let's go back into the view controller here instead of bold for that fun. Let's use a light light, uh, size instead and instead of to do, let's just try, create some tasks. Let's run that one more time with those changes and see if that looks a little bit better from kind of a you aux perspective. And I think that looks much, much better. So we have that set. We're good to go. Ah, and now let's go ahead and try adding a title to the navigation bar, and we can simply do that if you remember from how we did it into detail. View Controller is interviewed Load. We could go ahead and set that title property on the View controller to a string value. In this instance, it might make sense to just dio to do list. Simple like that. And now let's go ahead and run that and see what it looks like with the to do list set for the title. Looks OK and now for a final change, What we'll do is go ahead and uncommon the construct data source method just because weaken quickly, take a look at everything here and let's see if we can make ourselves a little bit smaller to decrease the vertical spacing that we have in between them here. So let's go back into the main storyboard and take a look at the cell subclass that we have on the to do list table view controller And when we go ahead and select our cell here and let's take a look at the, uh, actual size of it here, so we set that to a 1 45 height Now, initially, it looks kind of okay, but as we started to develop this further, it seemed like it may just be a little bit too tall for just how simple our data structures are. So if we want a decrease that hide vertically, we'll have to move a couple things around. Starting off, we can take our subtitle label here and scooted up a little bit, just ever so slightly right right up to the bottom of the title label. And remember that these Ah orange warnings here are saying that our constraints are still here. But we've moved our frame here, so we need to go ahead and either update the frame, which would then put it back here, which we don't want to do it or update the constraints to position it where the new frame is that right now. So with the label selected Weaken, go here to the resolve auto layout issues and just simply had update, constraint constants, and I'll go ahead and take care of that for us. Now, if we go back to the row height, let's start decreasing that a little bit at a time. Try to get something that looks OK now. It looks like our labels getting a little smushed there. That's all right. Let's drop it down to 1 20 and then we'll go ahead and take that label one more time, bring it back down, kind of flush to the edge here, and I think we could do a little bit better. Let's go ahead and take that sell and drive it down to 1 15 and see how that looks. We'll take that some title, able again destroyed and move it with the lay out. Guidelines are lining us up, Doc, and we'll update the constraints the same way we did it. And let's see how far away this label is from the title label, so we'll select it. We'll go over here to this button and receive that were exactly for away from the next label. So that's pretty close. Almost touching it. That's fine. So that will look better visually than what we had before. Remember here, even though we updated this row height to 1 15 we also need to go ahead and do it in the view controller because it's returning a row height of 1 45 because we haven't updated that , and that will override this 1 15 here and make ours table of you sell look bad from a visual perspective. So if we go back into the to do list table view controller. The final change will be it's turned this 1 45 into a 1 15 Now let's go ahead and run this in the simulator and see what it looks like. That looks a lot better, much less waste in space. And let's go ahead and comments out are constructed data source method here and create a task from start to finish with all of our changes in here and C are completed app. So Grayson tasks finish project coating and said it for tomorrow. Yeah, Good, Great. Look at that. Looks pretty good. We have everything set right as we want it, and it looks much better than what we had before.