Passing Data Between View Controllers (Swift 5, Xcode 12, 2020) - iOS Development

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
what is going on guys welcome back to another swift video in today's video we're going to be taking an in-depth look uh as to how to pass data between one or multiple view controllers so pretty popular pretty heavily requested so i figured we'd do a deep dive of the three most common ways so here's the app we're going to be putting together each of these tabs has some type of method of passing data in this first tab here we pass in via an initializer data into the second controller with the selected item and the related items so we're going to take a look at this approach the second approach is getting data from one controller back to the other via a closure so here we have a label on a button we can hit this and type in some text and when we hit done we pass it back to this controller and update this label and the third one is a way of passing data based on an event to all the observers so when we hit this button we actually pass the color red to this controller and this controller and we also tell this controller to get rid of its table so three different approaches all three are the absolute most common ways to do it in 99.999 percent of apps and we're going to look at each one in in depth and talk about pros and cons so that said make sure you start off by destroying that like button down below so youtube has to go back and fix that button helps out the video quite a bit if you're a returning viewer hit subscribe get excited get pumped open up xcode and let's dive into it quick pause before we get into the video if you haven't seen it already i am hard at work putting together ios academy.io a community where all of us ios engineers can come together learn how to build some of the top apps like facebook youtube and instagram in addition to interview prep to land some of these ios roles at top tech companies so if you're interested in the free and premium content to come head on over to ios academy dot io and enter your email address in the waitlist form and you will be notified as content becomes available that said let's get into the video all right so let's go ahead and get started by opening up xcode and creating a new project i'm going to stick with a single view application here and let's go ahead and call this project passing data between vcs make sure your language is set to swift make sure your lifecycle is uikit and interface is storyboard if it is swift ui you are going to get different files so it will be tricky to follow along so make sure all of that is set go ahead and save your project and before we start writing any of our own code let's go ahead and pick a simulator up here i'll go with the 8 hit that run button to build and launch your simulator that way it'll be nice and ready when we start adding our own code which we'll do in a quick second here wait for it to boot up that's not the one we want let's go ahead and close that one this should be the one we want and while that boots up let's go ahead and go to our view controller so as you saw in the beginning of the video we're going to take a look at three different ways to pass data between view controllers and let me just list them out here really quickly so we get a kind of a bird's eye view of what we're going to be covering so the first thing i'm going to do let's get rid of that the first one we're going to do is a custom initializer the second one we'll do is a completion handler or a closure and the third one we're going to do is a notification uh center post so each of these have distinct distinct trade-offs and advantages and disadvantages and we'll talk about those briefly as we go from one to the next so cool custom initializer so this one's uh pretty common and pretty easy to set up and the idea of this is you create another view controller obviously that you want to pass data to and you give it a custom initializer with your own parameters that you must use to pass in the given data so what does that even mean so let's get started first and foremost by creating a basic table view on our first controller here that the template gave us and we're going to select a cell in here and based on that we're going to open another controller so we're going to create the table with the anonymous closure pattern here if you're not familiar with this go ahead and just follow along and afterwards i've got a separate video entirely dedicated to this so take a look at that so here we're registering a cell that we can use we're going to add this table as a sub view we're going to say add subview for the table we're going to set its delegate and set its data source and we need to conform to those respective protocols so it doesn't complain it's a ui table view delegate ui table view data source and finally we need three functions so number of rows let's go ahead and say 20 sell for row we need and in here we want to dq a cell so we're going to dequeue a cell with the id we registered for index path go ahead and return the cell and let's just go ahead and set some random uh set some random label on here we'll just say hello and add in the current row position we do plus one since the rows start at zero and the last one we want is here and here is did select row add index path firstly we're going to deselect the row aka unhighlight it and let's go ahead and just hit command r and make sure our table view is appearing actually there's one thing i forgot to do make sure you assign the table of frame and we're going to say view dot balance and that'll ensure the table takes up the entirety of the screen like so also i'm going to go ahead and hit command shift a which will put the simulator into dark mode since it's a little easier to see so cool so we've got this table here and we can select the cells looking good let's bring in another view controller we want to pass data into so let's right click this and hit new file we're going to go and select a coco touch class right here and it's going to be a subclass of a ui view controller and i'm going to call this second custom view controller no need to check this nib file box go ahead and hit enter twice to create it and let's go ahead and get rid of this commented code let me go ahead and give this a title of custom controller and basically whenever we tap on let me actually move this up whenever we tap on any of these cells we want to create this custom controller so how do you create a controller so we can simply say let vc which stands for view controller name of the controller parentheses to create it and we can simply go ahead and say present vc animated true so now if you go ahead and hit run and if we click on any of these you see we get this other controller popping up the reason you don't actually see it is because there's no background color set on it so let me go ahead and give its view a background color so we can see it and let me go with system green get some nice colors in here so we click on this now we see the green controller popping up in a modal fashion but what we want to do and what we care about is passing data in here so before we can do that we need to actually set up some data here so in our first controller let's go ahead and simply create an array of some items so let's say private let data is just going to be an array of uh having an array of array of strings so we're going to do something like apple sony just some company names google uh microsoft let me copy and paste this and the next one i guess we can do numbers one two three four four uh let's do countries basically what we're doing with this data is we're gonna pass it into the other controller with a uh with a custom initializer which is the first thing that we got up there so instead of hard coding the data we need to use some type of collection so number of rows here is going to be data the section position and count we also want number of sections and we're going to return data.count and for the actual label we're going to go ahead and we're going to say this is data the given section and the given row position so let's go ahead and set up that custom initializer so it's quite simple actually so what you want to do is go ahead and just create an initializer on the other controller in here make sure you go ahead and call super in it and i recommend using this one with a nib name and bundle that's a nil for both of them you'll see you get an error here where it's complaining that you need to bring in another required initializer go ahead and hit the error hit fix and it'll stub it out for you you don't need to change any code with this but every time you create a custom initializer on a view controller you do in fact need to include this and it'll just yell at you you can hit the fix button but if you hit command b everything's compiling now so how do we actually pass in data so let's say we want to pass in two things let's say we want to pass in selected item of type string and we also want to pass in related items of type array of string so what we can do in this initializer is we can simply say this and the second one and before we call super in it we can say self.selected selected items is the inbound parameter of selected items and self.related items is the inbound parameter of related items now if you would command b you're going to see you have a build error the reason you have a build error is here we're trying to call this initializer without any parameters that initializer no longer exists because we created our own so we want to use this one now with a selected item and related items so where do we get these values from this is actually why we created the data array in this class so we're going to say the model rather we're going to say the items for this section is data index path dot section so for related items we can go ahead and pass in items and for the selected items it's items and the current thing that was selected in this collection and that's how we can go ahead and pass in the data into this other view controller now just for the sake of verifying let's go ahead and let me do two things so right now in the second controller we're setting the title to a custom controller let me actually move this down but instead of that let's go ahead and set the title to selecteditem.uppercase and on here let's go ahead and just have one label and we'll set the label text of that to be all of the related items so let me create a label here pretty simple label we'll say the frame is the entirety of the controller we're going to add it to the view we're going to say label dot text alignment is centered we're going to say label that number of lines is negative 1 so it's going to be as many as we need to show the text and finally we're going to say for item in related items label dot text equals label dot text plus a space plus the item and that should be good to go let's see why this is complaining value of optional type string so what we can say because this is an optional type we can say in parentheses here if it's nil go ahead and use an empty string like that hit command b think should be compiling hit command r to build and run and now you can see when we select on one of these we do in fact get the related items so these first things are companies here but if we go to one of these down here we get the different uh associated uh countries notice we don't have a title showing up here and the reason for that is we're not wrapping this in the navigation controller so go ahead and for this view controller presentation create a navigation controller here and pass in the vc as a root controller and you'll see when you select these now the selected item is shown up here so that's the approach of passing things in via a initializer moving on to the second one the second one is fairly simple as well what i'm going to go ahead and do is i'm going to start nesting these in a tab bar so we don't have to delete this code when i push it to github so go ahead and go to your main.storyboard and select this view controller come up here and in the toolbar hit editor and we are going to go to embed in as soon as i can find it there it is and we want to embed this in a tab bar controller like so and we're just going to create uh two additional controllers in here for our two additional uh things that we're gonna do so let me just drag on to ui view controllers so there is one and we're going to want one more the only reason i'm using storyboard for this is for the sake of time so we don't have to sit and design all that ourselves in code and go ahead and drag from the tab bar controller to this guy relationship is view controller same from this guy view controller and we need two classes for those view controllers so right click this new file you want a second view controller and you want a another one go ahead and call this third view controller and i'm going to select these and throw these into a folder so we know that these are the ones that are driving the tabs it's a new group with selection so we're going to call this tab controllers and just to make sure they show up let's go ahead and set their background colors we'll say this one is as soon as it decides to give me the autocomplete interesting it's not wanting to cooperate so let me actually just get let's get rid of those commented out code let's get rid of this comments that have code as well and go ahead and hit command r let's just make sure they are popping up here we should have two tabs or three tabs two additional tabs and they are in fact popping up here let's go ahead and try to get that background color to pop up again there we go background color for this one will be yellow and for this one it's going to be uh let's do [Music] blue awesome uh okay the reason they're not showing up the colors is because we never set the class in the storyboard so head to your storyboard select the view controller and on the right hand panel here go ahead and select this tab and give the class name you just created so this one is second view controller be careful because we call the first one second custom and this one if third view controller so i apologize for so much setup but it's pretty important to organize all this so we can better understand what we're doing but we now have all the colors showing up so let's talk about good old completion handlers for passing data so i'm just going to put a comment here completion handler model and what we're going to do for this example is we're going to have a label on our view controller here we're going to press a button that says enter text on another controller we're going to enter in our name and when we press done there we're going to basically pass the data back to this and where the label is we'll update it and we're going to do all this through code pretty similar in storyboard so feel free to follow along with the storyboard as well so firstly let's make sure our autocomplete is working so we want a label this is going to be a ui label and our autocomplete looks to be not cooperating so let me go ahead and close xcode and reopen it sometimes xcode decides to make our lives more difficult but if you close and reopen your autocomplete should start uh working as expected again to give it a second here you can see the syntax highlighting also gets fixed when you reopen let's go ahead and create that ui label beautiful it's working again and this is going to be a label we're going to say label dot text alignment it's going to be centered labeled.txt is name colon dash and we're going to return the label we want to add this onto the view so we're going to say add subview for label now we also want to create a button so we can go and enter in text so we're going to say let button is a ui button let's give it a frame uh we'll go ahead and say 0 0 250. let's go ahead and save view add sub view for the button we're going to center the button so we're going to say the button center is view dot center whoops view dot center let's add some text on it in this case a title we're going to say set name normal we're going to say button dot background color is going to be i don't know let's go black and let's make sure we can see our title so we'll make the title color white for normal and we also want an action to occur when the button is tab so we're going to say button dot add target self did tap button and the event is going to be touch up inside which is a standard top let's go ahead and create that function for did tab button and before we continue along let's go ahead and hit command r and make sure our button and label is showing up so let me actually make sure we're on the right simulator looks like xcode likes to reset the simulator every time let's pick the iphone 8 again and hit command r and give it a second there it goes okay cool so we have our button showing up where is that label so we never actually set a frame for the label so let me say label.frame is a cgrect let's say 0 50 the entirety of the width and let's say a hundred let's hit run one more time and we see our label up here now so cool so let's go ahead and show another controller and use a completion handler to get the data passed back so i'm going to go ahead and create another controller so right click new file cocoa touch class and we're going to call this text entry view controller and simply on here we want to have a field and a way to essentially hit a done button to pass back the data so for the done button we're going to use a navigation item we're going to present this controller in a navigation controller so let's say the right bar button item is a you are uibar button item and the title will be done style is done target is self action is did tap done done button whoops let's go ahead and create this action right below it the reason we need to put at objective c if you're not familiar is selectors are under the hood still in objective c so we need to expose it in swift and let's see let's give this a title of enter name now we want a text field on here of course so we're going to say field is a ui text field and let's create it in a anonymous closure here let's say field.placeholder placeholder is enter name we'll say field dot background color whoops let's get rid of my antivirus pop up here let's say the background color is white and that's probably good enough for this example let's make sure we add this as a sub view so add sub view is field and we also want to give this a frame so let me go ahead and give it a cg rect of let's say 20 100 the width of the screen minus 40 so it's centered and a width or a height of 55 and let's also pop up the keyboard on it by saying become first responder so now on the other controller that's going to actually go ahead and present it which is second view controller when this button is tapped let's go ahead and create the vc which again is wrapped in a navigation controller with a root controller the root controller will be the text entry controller and finally we can say present vc animated true go ahead and hit command r to build and run and when we go ahead and tap on this button here we should see this other screen pop up we've got our fields here i always forget to set a background color so let's come to this sorry let's come to the other controller which is this text entry and let's set a background color on here of white like so go ahead and run and hit that button again and we see this other controller here and we have this text field we can enter in a name here it looks like the text is going to be white default so let's go ahead and change that as well we'll say text color is going to be black and let me actually make the background here a light gray so we can see it better and now we could actually work on passing the data back from that text entry controller to this controller so cool we get this popped up we can enter in stuff in here it's supposed to be black i typed blue and when we hit this we want to pass it back so how do we pass it back with a completion handler it's actually quite simple you create a closure on here called completion it should be a var you want to make sure it's public so people can assign to it to other classes and its type is going to be parameters that you want to send back so in this case we want to send a string back a string optional because we might not have any text in the fields and this closure returns void and we may or may not have it so optional so now what we can do from the calling side the presenting side is as follows first of all we're going to pull this out here this text entry we're going to say the vc is text entry like that and on here we can now say text entry dot completion go ahead and hit command b to make sure the auto complete now picks it up dot completion is text in and this is how we can get the data back to this controller when this controller calls the completion block so uh two things you want to be aware of you always want to capture weak self so you don't cause a memory loop little out of scope for this video but for our example sake we're going to update the labels text to be the text we get back and also at a scope for this video we want to make sure we do it on the main thread so go ahead and wrap it in this dispatchq main async and then now on this text entry controller what you can do is when the user taps the done button we can call completion and pass in the fields dot text so let's go ahead and hit command r to build and run and you'll notice by default this is name colon dash let's open this up and let's type in some name and as soon as we press this one thing we forgot to do is dismiss this controller let's get rid of this dictation we don't want that but if we close this we see that this already updated so let's add in that dismissed call so when we tap that button we also want to dismiss this view controller for text entry so let's go ahead and hit this we're going to type in we're going to first say not now for the dictation that it keeps complaining about and we're going to type in a name in here we're going to hit this button let's make that go away again let's hit that button right there and we see we dismiss the controller and also see the update here let's try some other text you can just put in anything in here and we see we successfully pass it back to this blue controller beautiful the last thing we're going to do this video's actually gone way longer than i planned for but the last thing we're going to do is use a notification center notification to basically pass some type of data to these other two controllers so this one's quite simple actually pretty simple similar to the other other two we are going to have a button on here and when we tap the button we're going to basically fire off an event that these this blue and table view controllers will be listening for and when they receive that event uh they're gonna do stuff in this case uh we're gonna go ahead on this one or remove the table and set the background to red we'll also set the background to red here and here we'll basically do nothing so the point of a notification center event is you can pass any type of data it could be a string it could be a color anything that you can wrap inside of the actual notification payload so instead of talking about it let me just write out the example so we're gonna create a button here it's gonna have a frame zero zero two hundred and fifty we're going to say view add sub view button we're gonna say button dot center is view dot center let's give this guy a background color of black or blue i guess for now button dot set title is going to be fire event for normal and what else do we want we want the button title color to be white normal and most importantly we want the button to have a target and an action so did tab button for touch up inside let's go ahead and create that function here that gets called when we tap the button let's look at how to fire the notification so firing a notification is very simple you say notification center dot defaults and you want to post a notification with a name and an object you can also do it with user info and user info you can use to pass in even more data to the receiver of the notification something important to note is notifications can be observed by n number of classes so it's not a one-to-one communication of controllers you can do one-to-many so we're just going to use a name and an object the name is going to be notification dot name and we're going to say our custom so you can put whatever string in here that you want and an object is going to be basically anything you want so we're going to pass in a dictionary and this is going to be a dictionary of a string and a color so we're going to say ui color dot red and the receiver is basically going to pull this color out and assign its view controller's view to it so simple enough how do we actually go about uh how do we actually go about listening for this notification so pretty simple in this other in the other two view controllers in view did load we are going to say underscore equals notification center default whoops type in default correctly defaults and we want to add an observer and the one that we're going to go with you can either go with this one which returns a pointer to the observer or this one which calls a function i recommend this one for a variety of reasons but let's go ahead and paste in our notification name here the second parameter you can say is nil the thread you want to call this on is main since we're going to update the user interface and this is a closure in which the notification gets passed directly and you can do this let's go ahead and change this underscore to be an observer and the type of this observer is supposed to be a ns object protocol optional and once we basically get the notification in here we want to get the object out so we're going to say guard led object is notification dot object and we want to cast it as a dictionary of string and ui color else we're going to return then what we want to do is we want to say guard let color is going to be object for the key color else we are again going to return and finally if we get that color out we're going to say self dot view dot background color is color and in this can in this controller we're also going to hide the table we'll say is hidden is true i'm going to copy and paste this to the second view controller and we'll review this in a moment since there's a lot of code typing pretty fast so let's go ahead and paste that in here whoops we want to paste in a view to load actually which is this function right here and let's get rid of this table view call since there's no table view here and let me create this observer variable in here as well and as object protocol go ahead and hit command b and command r make sure it runs if it does great let's see if it works so we're going to hit this button notice these screens are blue and black respectively so we hit this this screen is now red and this one the table is hidden and it is also now red so let's go over that one more time so on this third view controller we have this button pretty simple when we call the button we post a notification with this name and the object in our case is a dictionary the key is a string and the value is the color red and the other two controllers what we're doing is we set an observer the type of an observer to hold on to it is this ns object protocol and the observer is saying observe for this notification this object is not the same as what you expect back so we pass in no we actually get the notification in the closure here and then we unwrap it we make sure we have an object we then try to get the color for the key color in the dictionary we assign it to the views background color and in this case we get rid of the table and then basically the exact same thing here and the only difference is there's no table so we just dropped that bit of the code and that's how you can use a notification center post uh and there you have it that's basically the top three ways of passing data between different view controllers whether you want to do one to another using a custom initializer which is what we've got going on right here let me close this for some more room so we created a custom initializer in this second custom controller we can pass in data you can of course use a completion handler which is what we are doing here on this text hint entry controller where the user hits done and we call this completion closure which gets the data back to this controller or third you can post notifications to pass data to all the observers so this video has gone pretty long i wanted to make sure that we got through all the explanations thoroughly the last thing i'll end up wrapping up with is best practices so notifications should really only be used where you really have a case of passing data to multiple observers you shouldn't be firing off notifications that are only meant for one observer for the case of custom initializers this is very popular and you should definitely use this if you want to pass in any data that's a requirement to a controller very simple to set up completion handlers i would say is the second most common and this is often used when you have asynchronous tasks so for example uh let's say the user needs to do some work on another controller and you want to get the results back in this case we're entering text a completion handler is by far the simplest and more straightforward way to set this up so that's about it so if you haven't destroyed the like button already make sure to do so for that youtube algorithm helps the video and channel quite a bit comment any questions concerns suggestions feedback i love hearing from all of you guys hit subscribe if you're a returning viewer or if you enjoyed this video for daily swift uploads thanks for watching i'll catch you guys in the next one
Info
Channel: iOS Academy
Views: 9,482
Rating: undefined out of 5
Keywords: swift 5 tutorial, swift 2020, swift, swift 5, swift tutorial, swift for beginners, swiftUI 2020, swift programming, swift basics, swift apps, make iPhone app, swift make first app, swift pass data between view controller, pass data between view controllers, passing data between view controllers, how to use multiple view controllers swift, pass data between controller swift, swift pass data between controller, swift 5 pass data between view controllers, iOS app swift pass data
Id: UVIQ7fkw_N8
Channel Id: undefined
Length: 37min 6sec (2226 seconds)
Published: Thu Oct 01 2020
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.