The Complete Guide to NavigationView in SwiftUI

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
[Music] navigation view is one of the most important controls of any swift UI app letting us push and pop views freely in this video I'm going to walk through the full range of navigation view features starting with simple things like titles and buttons then moving on to more advanced topics such as programmatic navigation how to do split views how to support Mac OS watch OS and more and this video is sponsored by revenue cat then it gets super easy to add in app purchases and subscriptions to your apps including half things like receipt validation handling churn and much more let n do the hard work so you can focus on the fun stuff your app okay let's look at some code you can see here I have text hello world that have thought iOS swifty white template let's go ahead and add a navigation view to here so I says a navigation view around our text like that and most of the time that will want the navigation view as a top-level thing inside your view the only reaccept in here is you have a tab view you have multiple tabs with each one having in their view then find yet a tab view of rounding a view otherwise it's a top-level thing now when learning swift one thing folks find how the layouts is how they handle titles for not views who do it like this would say text hello world dot navigation bar title is navigation we put it there attached to the text not attached to the navigation view that's intentional that's how Swift UI is supposed to work you see navigation views let's push and pop views get out of you out of you out of you to do to do each with its own content and each with its own title and that title will change primary secondary detail tertiary who knows what's gonna pop in there and it's down a swift ey to remove one title to animate it going away and animate in another title coming in and it'll do that for us while it does hash the content that's how it works we think about if we were taking this thing here is modifier attached to the navigation view which won't work as you see it's kind of gone away entirely now what we're saying is that's its title for all time which makes no sense in the uikit this makes sense for iOS or so do I any of us thinks it's just not a good idea it should belong to the thing inside the navigation view that's what's being shown right now so we have this title here now we should say doesn't have to be there they can be attached to any view inside the navigation view it had a V stack and a haystack then some text you put an app bar haidle there and it'll bubble upwards it'll propagate upwards to the navigation view like that now if you want to in customizers title the way it's shown with second parameter which is display mode has three options automatic inline and large the large option is what you see right now those super large chunky titles the inline option is smaller title like that little slimline title that's useful for detail screens then it's automatic which will choose the right option based on ever the parent had broadly speaking you want large titles for your very first view your navigation view and all subsequent views will have inline titles there are a handful exceptions that's the only time really otherwise large title then in light in life in line and actually large is a default anyway so if you take away that completely and get a large title let's remember the subsequent ones use an inline title there when it comes to pushing new views you can use that you can do that using navigation link you can say hey when it's up on this content this picture there's text if you want to push to a new screen and one of my favorite features of Swift ey is for prototyping you can say push to not a whole custom new view which I've designed but just temporarily some text or picture or even a a color or a rectangle just temporary stuff so you can prototype the first screen now you can do that here we can say our navigation view has a navigation link with the destination of text second view so I'm pushing directly to some text saying hello world like that and that is all it takes to do pushing and popping of views in Swift dy now if I press command R that should sprinkle immediately being well there we go so as hello world press that income second view but notice how swifty wise automatically made this hello world text blue its signal to users this thing is interactive it's blue for a reason it's an active piece of text that's a really helpful feature but can actually cause unwarranted unpleasant side effects things that you hadn't anticipated and it's particularly bad for images now I wanted to go ahead and add some images to your project now I'd miss already over here my data catalog I have happiness with logo this Redbird thing and pull a picture of me quitting back at the camera now I've chosen these two for a reason hacking with Swift is red with transparent gaps between those sort of streaks rice picture of me is fully opaque there's no transparency there at all so we like the content view and say that our navigation link isn't just text hello world anymore it is an image of the happiness of logo there's the logo let's do that now image worse sir there we go boom there it is but you can see it was bread and now it's blue it's been recolored blue by swifty wire - oh this thing is interactive which is really helpful and it has nice transparent holes in there just like the original they're a really really good job but if I have chosen my picture my photo now we see a Blue Square which is useless right now that's mostly a photo of me looking happy the camera is now a Blue Square so it's not clear at all where it's supposed to be it's a problem there's an easy fix of swifty why we can say our image has a rendering mode modifier using dot original use the original pixel colors to draw the picture like that and I'll see me a mall now what I would say here is we remove the blue tint so the image no longer looks interactive it looks like just a picture of me grinning at the camera there's no clue that'll navigate to a second view so you gotta be really careful here and say clearly somehow with waters around it or text saying click here whatever this thing is interactive click on it somehow now obviously pushing to text second view is not very exciting you want to push through it a custom view most of the time in real applications and you can replicate that here with a new view but I want to show you how you pass data between views I can say here's what was chosen now show it in your second view I'll make a new view up here struct a result view conforms the view and this thing to show result you got a pass in one piece of data what choice was made as a string I'll say VAR ba dee da ba dee come on buddy some view text you chose choice that's they want to show on the screen now now content view we can show that view using a navigation link passing in whatever they chose now I'm going to do a thing where they can flip a coin at either head or it's tails so we'll have two navigation links down here we'll say that is let's delete all this junk as a V stack with spacing of 30 boom like that I'll have to innovation links here will say first the text Saints note what's happening you're going to flip a coin do you want to choose heads tails then below that is our first Naville Inc I'll say navigation link and this has the destination of how result view and that will force me now to say what the choice was so I'll say heads and I'll say text choose heads like that boom let's go down a little bit into another direction link location link destination is result view choice is tails text choose tales like that boom so saying either push to the result with you with heads or push it with tails either way pushing to result view I press command R now which you better see that action let's find out if either coin now choose heads Bhumi toes heads back here choose tails so we're now pushing to a detail view the same one with two different values and the best bit is when we create result you here swift we'll make sure we specify choice we can't not we must always specify one string value called choice it's really really safe way of working now that's how we do navigation from a user's perspective one that when they tap something show a detail screen but swift UI also lets us have programmatic navigation as a second form of navigation link we can activate things when we want to and our own terms so we can use that now first I'll add our first is give us some code here at all this general meme meme or you can all go away you can all go away you can all go away boom like that so we have our simpler layout now we have now we're gonna say there is a nav link and destination is going to be some text again second view well the use that second parameter to this that the navigation link which is is active is this a navigation link active right now is it showing its destination right now that's what it means now this must be bound to some sort of boolean state property so we'll define that now we'll say the new property up here at state private VAR is showing detail view and it's false by default and we want to bind a Novation links is active parameter to that is showing detail view so we're saying that have link hey show the second view show this text thing here defined only when is showing me tell view is true so watch that like a hawk watch it watch it watch it to this true boom show the second view that's we're asking for here if you want you could have some content inside there of a mage or some text if you want to but you can also say this content is actually an empty view there's nothing on the screen to represent this thing which is really neat because now that becomes a whole nav link right there highly innovation just watching that presenters view we can now add our own UI the toggle that boolean when we're ready at our own time we can say button will do tap to show detail self-taught is shiny tell view equals true like that when that code runs it looked very similar there are text pressing it in slides our view it looks like a regular navigation link but it's not it's a button that set to Buddha through a boom that's being watched by our nav link which then pushes its text that's a bit indirect but its approach matters it's really really important because this is now our code we're gonna have all the code we want here more code here maybe save some settings maybe do a network request whatever you want to do all that work now and then we'll already set the boolean to be true so that's that's the difference here it's not a navigation link but always just forcing on the screen it's ours customized as we want now obviously we have 1 billion here to show one screen if we had three different screens to show here it'll be very very painful having 3 from billions now it's showing first view it's your own second view it's showing third view it's showing 8 for you grim right we don't want that as a better option if after you want to do you want to have multiple if destinations here they're being shown by these navigation links programmatically then you use a different initializer we can attach a tag to our navigation links this is your tag watch this value for your tag and activate when your tag is the value so we'll change our boolean here to be a selection optional string equal to nil and you can use everyone for tags but strings work very well I think you can use integers you can use custom types does it really matter will your string here but it's nil by default nothing's being shown right now and we can then say our second view text not this boolean instead we'll say the tag for this is second a selection what to watch is dollar selection so we're now saying this nav link should show text second view when the selection property is equal to second as I was saying right now into another one navigation link destination next of third view tag now will be third selection is still dollar selection and I can out of an empty view inside there to say municipal on the screen boom and now we have as many ways of showing different screens we want we can show you this button here is tap the show second and it will just do self dot selection equals second the tag for that view or tap the show third selection will be third attack for the third view like that let's run that back so his second income second view and his third incomes a third year now so you can see we're modifying this state property which our nav links are watching as soon as it comes to their tag it'll show their destination we can also use these state properties to hide views to dismiss views programmatically as well if I roll back my code little bit to a simpler example from earlier with a boolean it was here yeah yeah great so we have a simple boolean true again we can say is show the screen which is the say anything the true but after a period of time hide it again we're finished now hide to think so I'll do dispatch Q dot main door async after deadline is dot now plus two self-taught is showing detail view equals false so show they tell view but of two seconds hide it again that's right go back show it one to hide it boom and and that way we can show the thing by saying is true and hide it by saying a false now honestly it's unlikely I want to have a two-second GTD timer here but the concept the same no matter what you do when you are ready the official never requests when you finished loading me the savegame whatever it is to hide the current view go to a different screen instead exactly the same approach is active or tag and selection exactly the same so that's how you show and hide views we've looked at how you pass stated directly to views but I also want to show you how can you use the environment because the environments brilliant with navigation view because anything that belongs to navigation view its own environment automatically gets share with all the views it shows so I'll try us out I'll make some beta we can share class user conforms to observable object it has one at published property called score set to 0 into 0 that are they tour going to pass around I'll then make a second view that expect to find this value in the environment I'll say struct user I start start change view conforms to view at environment object by user conforms to user then var body some view and this is going to show the users current score and let them increase it by one so I say as a V stack with text a score is user top score and button will be increase itself don't use it up score plus equals one at an entire change you finally will make our content view down here create a user once at observed object VAR user equals user it'll then show that score somewhere on the screen so I'll say it scared of monsters code what do you have you can all go away text the score currently is you did not score and below that a navigation link pointing to our change view like that I say text show that I cannot show these help you boom like that now we want that user object but we made inside content view to be available inside change view and it could do that of course by adding adding down here dot environment object if you want to there's no need to because if you attach environment object to a navigation view every view it shows will have that environment object first you second view third view for 350 of you they'll all have that same shared environment you can say down here on alleviation view dot environment object is our user like that share it everywhere I press command R now hopefully you should see score zero show detail view score zero increase increase increase scores now three and back scores now three so it was shared by all the views in its stack and they'll all have their body property re invoked whatever its value changes so it is now navigation and sharing items and we'll talk at how we do buttons cuz you can add more buttons leading or trailing which is left and right for left-to-right languages like English you can add multiple on one side multiple on both sides it's down to you it's really really flexible and swiftie why can I try now let's get rid some code first you can all go away you can go away let's go back to my old pal HelloWorld navigation new text text couple T hello world there we go boom simple layout again we're going to start really simple I'm gonna say that this thing has a navigation bar button that modifies a score when tapped none of us knew that thing anymore a simple local value called school so I'll say at state private var score is zero then we'll show that in here we'll say score is current score like that then on a part title like that below that I'm gonna add some items one item particularly dot navigation bar I you see is leading or trailing so I'll do trailing and for the view I'm gonna say this thing is a button saying add one wood for impress the score plus equals one like that now the indenting please get quite complex with multiple items leading and trailing yada yada yada I prefer to put trailing on its own line and indent button like that it's a bit easy to read in my eyes for a comeback let see how it looks boom score is zero and one add one add one awesome okay there we go if you want buttons on the left and right you're just passed leading and trailing parameters but I might have said that here that we have a leading button set button will be subtract one self-taught score minus equals one I need a comma here because leading and trailing are parameter names so in it with that kind of thing boom you can see now I have the tabbing going on to make it more easy to read so we have now a lenient training button press command R see how it looks add add add subtract sir perhaps tracked brilliant if you are placed both bonds on the same side you could of course use a V stack you want to above each other but on iOS we normally have them horizontally aligned and not vertically aligned so I'll scrap leaving put button on my pasteboard and say our trailing button to you is a hate stack with let's place it in here our subtract one then I'll add 1 then n page stack like that again in the end it neatly now notice I remove the comma here H Dax our view builders not parameter lists so you want to have button one with no parameter no comment after the closing brace and then add one here and that back we should see the button side-by-side it's fine now boom there we go so I do add add add subtract subtract attract now I would say that buttons like this in that bar have a very small capital area so I encourage you to make them by hand and add padding around them so they're easier to tap users okay that's buttons done let's talk how we can customize the way our nav bar looks we can do things like changing the font its color its visibility and more however at this time support for this insights with UI is very limited you go down to UI kit for a handful of things in fact only really two things are available and swiftly why right now one of which is saying is the navbar hidden or not and one is a navigation bar back button hidden or not and that's useful because you could say go to this screen this important screen make a choice must make a choice before you go back so both it useful like navigation bar title we've been using quite a lot these two modifiers should be attached to the thing inside the navigation view not the navigation view itself it's a bit confusing because another modifier called status bar hidden which must be attached to the navigation view so I think is a bit of bit of thinking here I'm gonna try and show off in one-one code sample for you we can say at state private VAR are say fullscreen equals false that and then in our nav you let's get rid of some junk here accurate of all that it's fine boom we have a button saying toggle fullscreen now we'll do self dot fullscreen dot toggle and it will attach to that navigation bar title or fullscreen and our new modifier navigation bar hidden values are fullscreen at state boolean for now we're also going to modify or NURBS our set the status bar to be shown or hidden depending on fullscreen or not I'm Matt's attached using sewing it on the navigation view directly not the thing inside the navigation view so I'll say doc status bar hidden is also full screen so we have one inside that I view one outside the now view one where hidden is part of method name one where it's an argument label so yay for consistency anyway that should kind of work let's give it a try press commander so it's now it's now showing them the tapes bar and the navbar press the button boom away they go come back again notice how the button moves up take up control of the fullscreen space because that's a space of having freed up it's now usable by our view live great now when it comes to customizing the bar itself this thing here we can do things like colors fonts and so forth that's what we have to drop down to uikit if he's a UI kit that Knology called an appearance proxy which lets us modify navigation bars in our app and they're really broad-stroke things you can't say modify one navigation bar it'll do them all at the same time which isn't great there are several ways of doing this but the easiest way all most commonly see is in the app delegate when your apps finished launching here in this did finish warranty with opens methods called focal customize at the end so here's how my navbar should look his on my other control to look once that shared everywhere in the app so we'll do that here we'll say let appearance equals a new UI navigation bar appearance new and iOS 13 or later and is that you customize the way in that bars look I'll say first that our parents had a default configuration within a peg background configure this thing ready for some sort of solid color in the background now the appearance has a background color of red so nice and bright so you can see on the video really clearly that's our background color done the next episode customized the way fonts appear inside there so I'll say the new attributes dictionary called utters there's a dictionary of NS attributed string string key I've been a come on here sorry : key add any equals a dictionary of dot foreground color I use UI color dot white and then the font I'll use UI font font come on font top mono spaced system font of size hardly 36 and wait I'll do black boom we can now attach those attributes to be the large title text attributes for our appearance we can say appearance but large pile text attributes the thing to use where the text is nice and chunky in the navigation bar is our attributes and finally use the navigation bar dot appearance its proxy to all religion bars dot scroll edge appearance equals power appearance this be used when I've used up against a very edge of the navbar I press command R now hopefully boom bright red background and then a white text color there as well I'll be careful by the way we're in UI kit land now which is why you're seeing a full red they're seeing a really primary red there if you've had you certain like system red instead which is the UI kit way of doing adaptive red colors then you'd see the sort of more pale red leads to in Swift UI anyway so that's why we can customize our navigation bar inside parts of to UI but most of the UI kit and help without change soon with as Swift UI improves next up I want to talk of how we can do more advanced navigation because there's one of the most interesting behaviors of Swift UI it's when we have landscape in big devices I'll show to you now let's first get rid of our customization with all this junk up here you can all go and then in our content view let's get rid of all this stuff the doom and then I'll do text hello world again I'll do primary and primary and then geared of that I heard of that okay super simple layout now again and you can see prairies up here and primers down here that's exactly what you expect but I'm learning on an iPhone 11 Pro max so if I put this thing into landscape the screen goes blank and I have primary the back button oh and that's pressed we get this slide over so what's happening here is swifty Weis trying to be helpful but the result is often you're staring confused where did my UI go it's all disappeared what's happening here what's happening is that swifty why automatically considers landscape navigation views on large devices like this one or most iPads for example in the fullscreen to form a primary detail a primary secondary split view where two screens can be shown side by side now there's a lot of variation how this works because of the way I pad works is your iPad apps in full screen you'll have your two views shown side by side if your iPad apps in split-screen with most of the screen it'll still be side by side but as it goes down to a tiny bit of screen it'll become collapse down to a single view and an iPhone in portrait it's a single view then landscape its split view with a slide over like this so it's all hooks of complexity here now to fix this we can we can just do what do I expects they want us to have two views in here one for the primary one for the secondary that's what they really want us to have here so we can accomplish that very easily there's our primary view we'll do text secondary boom Add to view directly to our navigation view and that'll 50y once and then after on the code again you will see in portrait mode we have primary in landscape mode we have secondary with primary being a slight other thing right here so you'll actually want to the other option is to collapse this thing down to have only one view of time which is possible using a new modifier called navigation view style and this is on the navigation you directly so I say dot navigation view style is stack navigation view style that means only show one view at a time no matter what device I'm working with to run that code again portrait you see primary in landscape you see primary that whole split view things gone away now on iPhone and iPad I understand why folks want to do this because the site simply UI it's not great for iPad because an iPad you want to have these two views sitting side-by-side but I don't have these sort of massive fullscreen animations because one of the benefits of having the regular navigation view layout no touching this thing entirely is that you have these two views side by side on iPad of course but any navigation links you have in the primary view don't show in the primary they're shown in the secondary which means you get a sort of like mail layout or notes layout you have on the iPad where you select from things or you select become visible in the detailed view straightaway it's a much much nicer way of working with complex data so I'd recommend you avoid stack navigation view style that you really really need it okay that ends how we're looking at iOS navigation view just briefly I want to look how I can deal with problems on watch OS and Mac OS because one of the things I swifty Y is yes it's a cross-platform framework but it's not designed to write once run anywhere that's Java in theory swiftie wire is designed to be right once apply anywhere learn the thing once how you do these things how you solve problems and apply that knowledge anywhere so it's different and this manifests itself sometimes because some Kobe write won't work in other platforms for example if I make a new watch OS project in here let's use watch app I'll call this thing navigation watch on dressed-up that as quarters lots of stuff all over the place care of some stuff makes me space to the dear if I were to have a navigation view here in my watch OS code I might say something like there is a navigation view inside there there is a navigation link and that goes to the destination of texts second view use my text hello world side there like that and that's pretty vanilla iOS navigation view code here is my hello world where as tap show the seconds you did that you know 20 months ago for iOS that won't work on watch OS press command B get errors right away navigation view is unavailable in watch OS they expect you to have a raw navigation link like that with no navigation view around it that's how it works on watch OS so this means if you're trying to share as much code as you can you can share a heck of a lot of surf do I try and get as much as you can and you're like oh I'm so close just navigation music working watch OS this is really annoying cuz now you haven't got an ovation view to work around anymore we have a different structure in what choice is very annoying fortunately we can write a little shim a little rap around here to make this thing work in Swift ey with no performance impact that'll be just a nicer way of sharing more code we do that by saying hash if OS is watch OS and hash endeth and everything between these two lines will only now apply to watch OS and we're doing it like that so we don't pollute iOS or Mac OS or CVS or any other platform we only want this to affect watch or West code inside there will say the struct called a navigation view and it is generic over content which is some kind of view and itself of you it'll have one property called content which is a function that returns except no prams and return some content a view to render Clemmy initializer which is a view builder content escaping which is a method function that returns content boom sign that to be its content like that there its body we'll do some view or we'll save the watch OS navigation view is your V stack with spacing of 0 inside there just draw your content like that so we're saying there's a new strike core navigation view which draws some sort of view content is itself a view now it's made Italy pass some content just stash it away for later and then draw that content inside a zero spacing V stack so it has no performance impact us at all and now you press command B and a code will build so we've shared more curves with iOS and watch OS it's an easy win after Mac OS let's get rid of that and make a new Mac OS project Mac OS app I'll do a navigation Mac desktop can make lots of space you can go away you can go away massive big preview area doing that stuff again with a simple example here we'll say there is a navigation view and then Texas here I'll say this thing has a navigation bar title of navigation again a trivial example on iOS but that's not gonna work on what Mac OS errors all over the place it doesn't have a navigation bar title modifier Mac OS so it has navigation view but not narration bar title it's like the inverse of watch OS which had known Avenue and had a title so it's problem it's another problem and thinking well I had shared so much code I could share lots not a code here but I'm hey held back by a simple kind of meaningless trivial modifier just show knavish and somewhere at the top fortunately a gamma can do a little shim we can say hash if OS is Mac OS again end if now remember that if OS and end if means we're not polluting the cove iOS to us watch mice one other dessert was it only fitting Mac OS right here and now we know an extension on view only for Mac OS that re-implemented navigation bar title modifier take some sort of title string return some view internally we'll just pass back itself do nothing at all transform us in no way whatsoever and that in theory ought to be compiled away by the swift compiler it won't even exist and with that change now our code will compile on Mac OS so again it's a super simple change to make from our end really really light on swift and Swift UI but it does mean we can share a little bit more cross-platform code not everything you still can't share everything it's not write once run anywhere you just learn it once and apply everywhere but the more code we can share the better of course ok that's the end of the video I should say if you enjoy this video subscribe to my channel I make lots more videos like this one teaching you Swift UI Swift UI kit sprite kit and more right here on YouTube free of charge with correct navigation view extensively here if you wanna see more v UI I've got a massive free tutorial series called the 100 days of swifty why it's at hacking Swift calm slash 100/50 why don't check it out and a half swifty why by example a huge huge like for two pages something resource guide answering common swifty wire questions with hands-on real-world code samples again it's all free online and put your own URL below me somewhere here in the video so you can see it there go and check that out and if you'd like this for me on Twitter I am 2 straws once again I wanna thank revenue cat for sponsoring this video they make it super easy to integrate in app purchases subscriptions receipt validation and much much more in your iOS apps trust me I've done this code myself with store kit it's extremely hard to do subs are really hard to do let them do the work they've got a really brilliant amazing great value free plan you know nothing it's like ten thousand dollars a month completely free about paying their penny go take them out at revenue Capcom you
Info
Channel: Paul Hudson
Views: 125,483
Rating: undefined out of 5
Keywords: swift, swiftui, ui, navigationview, navigation, view, tutorial, xcode, navigationlink, navigation link, ios, macos, watchos
Id: nA6Jo6YnL9g
Channel Id: undefined
Length: 39min 17sec (2357 seconds)
Published: Wed Apr 29 2020
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.