SwiftUI - How to do Navigation in your Swift UI app

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
a code crew it's Chris here back again with another Swift UI tutorial today we're gonna dive even deeper into Swift UI and we're going to look at how to display lists of data in your view now if you've used the UI kit before in the past we've done this with the UI tableview element however in Swift UI it's a little different you're also going to learn how to show a second view and navigate from the first view to the second view and yes you're also going to learn how to pass data between them sound good alright stay tuned alright so by the end of this tutorial you will have built something that looks like this now I know this looks like the one that we built in the first part but take a look at this we have got a whole list of landmarks now and when you click on each one it's actually dynamic yet a detailed view of that place with a map of that place and a picture of that place and obviously this demo builds upon the one that we'd built in the last lesson so if you haven't gone through that yet I highly recommend that you do that first and again like I mentioned in the previous lesson these tutorials are based off of Apple's own awesome swift UI tutorials this particular one is called building lists and navigation and if you go down you're going to see that there are a couple of distinct sections so let me just go through a quick preview of what we're going to talk about in this lesson so they're gonna start us off with a sample project it's gonna have sample data already of the different landmarks we're going to create a view for each of those rows well actually we're gonna create one row view but we're going to use it for all of those places we're going to be able to customize the preview so remember in the last Lawson I told you that there are two struts in each view the first struct describes the content in the layout whereas the second struct actually dictates what you see on the right side preview and this gives you the flexibility to manipulate the preview to see only the parts you want because you might not be working on the full viewest so you don't need to see the full thing so in this part we're gonna show you how to customize that preview so you only look at part that you want to and then we're going to dive into the meat of the lesson which is creating the list of landmarks and this is what you saw back here with kind of the scrollable list that looks like a table view if you're familiar with the old way or the uikit way of building lists and then of course it's going to be static at first and then we're going to make it dynamic with the data and then we're going to set up some navigation between that list and the detail view which we built in the previous lesson so you kind of need to have that built we're going to look at how to pass data between the two views and then lastly this section generating previous dynamically you're going to learn how to preview your view in different device sizes so if that all sounds good let's dive in but actually one thing if you haven't hit that like button yet or you're not subscribed to the channel please do it really helps out my channel and it lets me know that you guys want to see more Swift UI tutorials so if that sounds good please give this video a like and subscribe alright let's do this so the first thing we're going to want to do is to go to this tutorial link in the description and go ahead and download the project files because it's going to start us off with a starter project that's going to contain some of the files that we're going to need to complete this project namely the sample data some helper methods and structs and classes now in this particular swift UI tutorial it only focuses on the Swift UI part and it doesn't really explain all the stuff that's in the starter project but don't worry I'm gonna go through that stuff with you guys just in case you're not familiar with some of the things that they're doing in there already so I've already got the file downloaded it's this one building lists and navigation dot zip so I'm going to go ahead and open that and it's gonna have two folders completing a starting point and obviously you know want to grab the starting point one let's go ahead and open up that actually I'm gonna do it through the Xcode 9 beta although so it doesn't get confused as to which version because I have both versions on here so let's go into desktop sample apps this one right here just starting point landmarks and open up there sample project yep all right so it's gonna start us off like this so before we dive in and start coding up some you eyes we're gonna take a look at what they have here and they've organized that really nicely for us in these subfolders so first of all let's look into resources here we've got landmark data JSON and if you're not familiar with this JSON format it's basically a format to describe items of data that we're going to use in our app let me let me show you so this outer square bracket is basically a collection of items and each item is separated by a comma so you see a comma here and a comma there and each item is surrounded by a pair of curly brackets and then the data inside is the actual data for that item so you see we have things like name category city state ID park coordinates for the location and the image now the images they're all here in the resources already so we have all of this set up ready to go the problem is that this data in this JSON file is not usable as is we actually have to process this JSON file and turn it into Struck's or things that we can use so that is what inside the model you have this data file that's what this is so let me just close go editor only and you can see here that it's got this load function now I'm not going to describe all of this code but it basically takes that JSON file and breaks it up into a collection of landmark objects that we can use and then notice here that they declared this global variable called landmark data which calls that load function and passes in the JSON file all right so this landmark data global variable is going to contain that array of landmarks and if you don't know what an array is it's just a list of items to put it simply there's also another image store class here and this is actually a singleton class now this is going to help us return these images in the sizes that we need so I'm not gonna dive too far deep into this it's a lot of code here to do that but when we finally get to using it I'll point out to you exactly where where it comes into play but for now we have this data file here we also have land of mark dot Swift now each of these landmark objects represents one landmark from the data file remember how the JSON data file was a collection of landmarks separated by commas well each of those landmarks is going to be represented by this struct here so one cool thing I can do for you is do a side-by-side comparison of let's see here resources nine Mark JSON let me close this was that alright so here is that landmark structure and here is our JSON file so you can see that in maps right we've got the name it's going to go into this property right here we've got a category that's going to go down here and you can see there's a one-to-one mapping there's an ID there's ID image name and coordinates image name and coordinates and then park and State Park and a state all right so that's really cool now let's go back to the file navigator all right so let's go ahead and open that close that dual window we've got the app delegate the seen delegate I describe this stuff back in the previous lesson so take a look at that if you're not sure what these are here is landmark detail about Swift now this is actually the thing that we created in part one this is that Turtle Rock Joshua Tree National Park detailed view so let's just preview it to make sure that it looks correct otherwise wheel we're going to be building off of a wrong base already so it's gonna take a while all right under supporting views while that happens I'm not going to click away from it we also have circle image and map view so these are two views that we've built in the previous lesson that are used in the landmark detailed view you can see that this is the circle image and this is the map view they're used in this to build out the overall detailed view so you can see there and the map is not showing up because we're not in live preview but if I turn that on you're gonna see it go to turtle rock all right so that's what we've got starting out now let's dive in and start building our row I'm going to do this under the supporting views group because this is a single row in a larger list and so I consider that a supporting view so let's go ahead and create a new file right there and under iOS choose swift UI view that's what we've been doing for the last little while right landmark row let's create that and let me just show the preview this is just going to be our basic hello world UI view but we're going to change that so inside this structure that describes the content and layout you know this this label could let me change this to let's say Turtle Rock right now this would be a static piece of text and we don't want our rows to be static pieces of text we want them to be dynamic because each row represents some sort of landmark we're going to store the landmark that this robe represents in a property that we're going to declare up here so let's declare and you probably called landmark and it's going to be of type landmark all right at this point if you try to run it it's going to fail so you'll notice that now when you try to create a new landmark row object that this doesn't work anymore you need to supply the parameter that is going to be set to this landmark property so why don't we use autocomplete open up a bracket hit enter you can see now that whenever you want to create a new Atlanta murkrow object you're going to have to pass in a landmark object to set to this property so what we're going to do is you know how I showed you that there was this global variable called landmark data and that this loads the JSON file and parses it and returns to us an array of landmark objects right well this is exactly what we need so why don't we access this global variable to pass in so that we have something to show so I am going to call land mark data and I'm going to access the first element now this preview is basically going to create a new landmark row it's going to pass in the first item in our data set which is going to be set here and then finally for my text element I can actually access the name property of the landmark that got passed in so name and let's see what we get on the right-hand side so you can see here it says Turtle Rock now don't be fooled because I had turtle Huck there before let's say I change this to one right you can see now it's silver salmon Creek and the order of these elements corresponds to the order of the data in here in the JSON file alright next we're going to add an image beside the name so let's go back here since we have the landmark that we want to show for this row let's see what else is in here so this landmark actually has an image property which returns to us an image view and we can pass in the size that we want so let's say 50 let's see how that looks like well actually this is going to crash reason is because if we want to show two elements side by side remember we have to use an H stack or a horizontal stack view so let's create one like that and let's just cut and paste these two elements into here well let me just indent this so it's a little easier to read ah I know why it looks so weird let's create more space there we go so we've got our zoom there we've got our image and we've got our landmark name so what is this image property why don't we go take a look hold down command you can click it jump to definition so we can see what this function returns you can also use that shortcut key right there so this is our landmark structure this is the image function and it uses that image store right and it accepts a size and then it returns us an image so this image store is what I pointed out to you earlier inside this data file remember here image store this guy so all this code right here basically reads the image from here turns it into the size that we want and returns it so that's what that was is responsible for so let's go back to our or where were we here landmark row all right so we've got an image we've got the text but it's kind of centered right and we want our rows to stretch for the whole width so let's close that I'm going to add a spacer at the back here now that's cool it's going to push it all the way to the edges like that now I am going to change the preview because after all we are working on a single row here right and what we see on the preview is like this giant screen this whole view we don't need that we just need to look at a single row so you can actually modify what we see in terms of the preview so for example take a look at this we can call a method called preview layout and then we can pass in fixed we want to look at a fixed size for the layout and for the width I'm going to put 300 in the height I'm going to put 70 so let's take a look at how that looks like so here we can focus on a single row so what's even cooler is that I can actually preview a couple of different rows or three or four however many I want by using something called group so let me declare a new group here and let me put this row in here all right so that's showing my landmark data the first element let me just create some more space and let's say I want to take a look at another piece of data for my preview so that I can make sure that the view that I'm coding here works for my sample set of data so here I've created two landmark rows one showing the first item in my JSON data file and the second one showing the first element for my JSON data file and what I noticed he is that there is actually a couple of margins in the top and bottom I want to have a margin on the left as well and so I can add some padding to my H stack so I can say the leading edge let's say 10 like that so that gives us that little bit of padding there now to simplify this code because this isn't a group I can actually apply the preview layout to the entire group instead of to the individual elements inside it so I'm going to delete that and I'm going to just call preview layout on the entire group alright up next we're going to see how we can start displaying a list of data now that we have our rows so let's go back here and let's create a landmark list so we're going to create a new file and I'm actually going to create it out here because this is not going to be a supporting view it's actually going to be our root view once we're finished with this so under iOS let's choose Swift UI view and then why don't we call this guy landmark a list so I'm going to move it up here so it's just easier to reference and see all right so again we've got our basic hello world with one text element so in order to display a list of data we simply use the list element so that's as easy as it gets I'll list like that all right and then we can paste in a couple of landmark rows right that's the thing we just created here so why don't we try that so land mark whoops landmark row and landmark row when I try to create a new one it expects me to pass in a piece of well a landmark data right a landmark object so let me just create two rows first so it's easier to see for you so I've got two landmark rows right here and inside each one I'm gonna pass in a different item from our data set so landmark data element zero and landmark data element one let's take a look at what we get right here so instantly this preview is so cool we can see Turtle Rock in silver salmon Creek so this is cool and all but this is not exactly what we want right because we're showing - static pieces of information here and in our collection of landmarks we actually have a lot more places and so I don't want to be hand coding you know each row like this what we want to do instead is actually make our list read off of our location data array let's just delete this and we can do that by using one of the initializers of the list namely this one right here so we can pass in our location data array I know this kind of looks like a mess but not a location that I keep calling it location data landmark data but the problem is that we need to exactly specify what the unique ID that uniquely identifies each item is and luckily for us for all of our landmarks we actually have an ID that is meant for exactly this purpose and you can see in the landmark data though Jason we also have the ID and each of them are different as well so going back here creating our list right here landmark data is our collection of data and we're going to call identified by and here we're going to specify the property or the key that we want to use and that is ID now I have to hit backslash because I need to escape the dot there and that's how you specify that you want to use this property as the unique ID now for selection I'm not going to do anything with that that's an optional parameter and for the action again also this is a little bit of a mess I don't have to specify that but for the road content I do want to specify this closer closure so let me double click that it's going to open up as a trail enclosure and this kind of looks it's really hard to read all right so now it's a little more clear and this I just have to specify a parameter I'm going to call it landmark so let me explain what's happening here so we're creating a brand new list and we are passing in our collection of data telling it what the unique identifier is so it can tell how many items there are and what items are with what items for each of those items in the collection it's going to run the code in our closure right here this is where we want to return the view to display that specific piece of data that it is looking at right because it's going to go through this collection so we basically in here we want to return a landmark row you know the thing that we just built so we're gonna create a new landmark row we're gonna have to pass in the landmark that's not a problem because we have it as a parameter up here so I'm just going to specify that all right so this says it returns a view but it actually we're returning a landmark row to be more specific so let's replace that right there and we should be good yeah all right so you see it's pretty cool now the list is dynamically reading off our of our data set and producing this list now one more thing I want to show you is you know how for our data set here our list of landmarks we have to use this identified by and tell it which property to use well we can actually improve that for our landmark structure if we say that it conforms to the identifiable protocol and if we just take a look at that so that we hold down this and you can see that it is a type that you can compare for identity equality open it up in developer documentation and let's just take a look here there's not too much information about it but what it does say down here is it is you need a unique identifier and an ID property here right so we don't really have to do anything else because it has that property right there and so now that the landmark structure conforms to the identifiable protocol we no longer have to manually specify this method here and then we can just specify our collection of landmark objects like that so now we've got our list of data but how do we transition from this list to the detail view when someone taps on one of these rows well for that we need to put our list into what's called a navigation view and then for each of these items that it generates these rows for instead of just returning a row we need to return that row wrapped inside of a navigation button so that allows the user to tap on it and then we can trigger some sort of destination for that button so let me show you how that's done so first of all we're going to declare a navigation view and then all we have to do is put our list inside of it so that takes care of that but the second issue is that we need to wrap our landmark row in a navigation button so navigation button here and we are going to create an instance of it now there are a whole bunch of different initializers for this navigation button but as I was learning Swift UI through the Apple tutorials I noticed that all we needed at least for this particular case anyways was to specify a destination so that's what I'm going to do here I'm just going to choose this one I'm going to get rid of the label I don't quite fully understand how the navigation button works yet but I'm sure in time as I dig more into Swift UI I'll learn but for now if we specify the landmark detail view if we create a new instance of it right here like that when this navigation button triggers it's going to send the user to the landmark detailed view and then this is how we would wrap this landmark row inside this navigation button now I I was encountering this error here and it's basically saying that right here we're returning a navigation button but up here for this closure we are specifying landmark row and then what I eventually realized is that we don't need to specify a return type actually at all so if we leave it like that everything's going to be good and then inside here we can try and run it again let's go a live preview load all right and we tap on one of these so we can go to the detail view there's a back button and we'll get you a different one but you notice how they are all turtle rock right no matter what I choose it's showing turtle rock and that is because inside the landmark detailed view we have these hard-coded values right it's set to this particular text here the circle image itself is hard-coded to this image and the map view itself is hard-coded to this coordinate for turtle rock so actually if we want to make it dynamic we need to update this landmark detail right it's got to keep track of a particular landmark that it wants to display and then we have to pass in the coordinates into the map view that we wanted to show we need to pass in the image into the circle image view that we want to show and we need to pass in the landmarks named Park state into all of these fields here to make it dynamic so let's take a look at how we're going to make this happen so this is the landmark detail why don't we go up one level and we go to the landmark list so here's what we want to do this is the list that is showing each landmark from the collection of landmarks for each single landmark it is showing a row right and this row we made a dynamic by passing in the landmark that I wants to show and then it's showing that landmarks picture and that landmarks name that's exactly what we need to do here as well for the landmark detail that's and that's gonna make it so that when they tap on Twin Lake they're gonna get the landmark detail for Twin Lake right icy Bay they're gonna get that landmark detail for icy Bay so essentially we want to change the landmark detail so that we can pass a landmark inside so why don't we now drill down to landmark detail and see how we can make that happen so the first thing I would do is create a new landmark property here right so that we make it so that when we declare a landmark detail we need to pass in the landmark that we want it to show like what landmark do we want the detail for right we need to specify that so now because I've added this landmark property here whenever you create a new landmark detail object you need to specify the value for that so right now in this preview I'm going to just put in some piece of dummy data we're gonna say landmark data let's say element number 3 just for sample data purpose all right you're not gonna really see anything change here you know why because all we're doing when we pass in landmark data 3 here is we're setting this property to landmark the third data element but the map view is still hard-coded to those coordinates the circle image is still hard-coded through this image and all of this text is still hard-coded so the first thing we can do actually is we can change this text right so instead of hard-coding that we can show landmark dot name right that's from this property up here all right so it's already going to be dynamic let's resume build failed that's because that's because now that we've added this landmark we need to go back to the landmark list right this navigation button this is no longer valid we can't just create a landmark detail we need to specify which landmark you need that too so let's do that and then we're gonna pass in landmark just like we're doing here for the row okay so that should be good all right build failed in so here in scene delegate again we need to the route view is landmark detail right when you launch the app it's going to show landmark detail and again that's no longer enough we need to specify a piece of dummy data for now so eventually we're going to want to change this to show the list at the root view actually why don't we do that right now we're going out of order a little bit so we're going to show the landmark list as the root view for when the app launches so that's eventually what we want to do anyways so this is in the scene delegate all right let's save it and let's hit command B and build it make sure it all runs and let's go back to landmark detail alright so this is where we're at here we've got the landmark property being passed in and I am updating these hard-coded strings to show the values from the landmark that is passed in so this would be the park and this would be at let's resume this would be the state and the market dot state and so I want to see those values update right there so regenerating all right so we've got st. mary lake Glacier Glacier National Park and Montana and this comes from this piece of sample data that I supplied for the preview now we need to update the coordinates in the circle image so we want to make it so that we can pass in the landmark right into the map view and pass in the landmark into the circle image to let it know what it should be displaying so why don't we do the map view first let's drill in jump into the definition for the map view here and up here we are going to declare variable or property rather for the coordinate and this is going to be CL location coordinate too deep and this is basically going to replace this line of code so we don't have to hard code these coordinates so why don't we erase that all right so now in the preview we're missing the parameter right for declaring the map view because we just added that store property so now we have to specify coordinate right I'm going to specify a sample so landmark data let's do the first piece and we're gonna say a little location coordinate like that so that that's gonna be Turtle Rock that's the first element but that's all we need to do for the map view so now it expects us to pass in the coordinates that we wanted to hone in on all right so now let's go into the circle image and up here let's look for an image let's create an image property right there so whenever we create a new circle image view it requires us to pass in the image that we want it to show so no longer are we gonna show a hard-coded turtle rock image we are going to show the image that is set here all right so circle image now for this preview we can't just declare a new circle image we need to pass in an actual image so I'm going to grab keep doing that I'm mark data I'm going to grab that's the first element or the second element rather because then a race starts at zero so the first element is 0 second element is 1 so I'm going to grab element the second element and then I'm going to call the image and the size of this was 250 and I know that so when we run this missing so it doesn't build right now because in the landmark detail we have to supply the parameters when we created the new map view in the new circle image so let's fix that first all right so this is the landmark detail we've already dynamically set the landmark named park state and we've just modified the map view in the circle image to accept the coordinates and the actual image file here so let us call the new initializer we're going to pass in the land mark dot coordinate location coordinate and for circle image we are going to pass in the landmark dot image for size 250 and we're going to zoom so sweet for it boom is that mapped I'm not gonna update ya should update there we go cool so now we can go back to our list because everything is dynamic now we've changed circle image to accept the image map view to accept the coordinate a landmark detail to accept the landmark and we've already updated the landmark list right here when we show the rope and we create the navigation button we're passing in the landmark to the landmark detail so now if I tap on any of these come on let me try to get out of this preview and try and get back into the preview so you can see there's still some things to work out but there we go Turtle Rock chili cook trail and all of this is dynamic and it's passing the data from the list to the detail view it's just really really cool now there is one thing I forgot to show you guys which is basically to set the navigation bar titles so in this navigation view you can actually call this navigation bar title here and then you can pass in a textview and that's going to show up landmarks that's going to show up up there let's see if we can see that mmm not really I don't really know where that's supposed to show up to be honest all right you know what we're gonna try to launch it in the simulator and see what happens all right so we've got our iPhone 10s on iOS 13 alright so we don't have a navigation title here either so I don't really know where it shows up if you guys know let me know in the comment section below I did something wrong I crashed it I know what happened there yeah keep in mind this is all beta software everything's on beta so don't expect everything to work perfectly however in the landmark detail I actually in here probably set a navigation so we're gonna do that here the navigation bar title display mode maybe that's what we needed a display mode so this one we're gonna make this one dynamic right because I'm passing the landmark name because this is the detail view and then for the display mode let's say in line let's see if we can see that in more detail it's not showing me at the right preview for the right view that I'm looking at come on I think it's it's basically giving up on me ah there we go and you don't run it well it's got an app icon and everything - ah there it is Turtle Rock cool yeah so maybe this list here we have - if we wanted to show it you know we could change this to what was it display mode docked in line let's run it nope well yeah well okay so what we're gonna do now I promise to also show you how you can preview it on different devices here so you can see here on the landmark list we're just showing it but if you call the display previewed sort of preview device come on autocomplete there we go we basically pass in we create a new preview device and we pass in the wall value and this loots this string I don't know where they get this from but it is basically something like this let's see if that works all right so finally I wasn't even looking and it changed cool so there's also a way to preview your preview on multiple devices at the same time now I'm not going to show you the code here but if you're interested just follow the link in the description to the Apple swift UI tutorial that this video tutorial is based off of if you go all the way to the bottom you're going to see the snippet of code that they use to show multiple device previews at the same time now I want to turn it over to you did you install any of the betas on your machines I know in the past that I never install alpha beta software on my machines but when they announced with UI I just couldn't not install it so I bit the bullet and went ahead and did it so far so good I haven't noticed any big problems let me know what your experience has been by leaving a quick comment below if you like this video please hit like and please subscribe to the channel as that sort of stuff really helps me and helps the channel grow and if you want to see more well there's more Swift UI content right there alright thanks for watching I'll see you in the next lesson
Info
Channel: CodeWithChris
Views: 67,762
Rating: undefined out of 5
Keywords: swiftui, swift ui, swiftui list, swiftui tableview, swiftui preview, swiftui navigation, swiftui tutorial, swift ui tutorial, swiftUI tutorials, swiftui basics, swift, codewithchris, code with chris, ios, xcode, xcode11, swift ui list, swift ui navigation
Id: wbFuAs_UNYg
Channel Id: undefined
Length: 41min 58sec (2518 seconds)
Published: Thu Jun 06 2019
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.