Your First SwiftUI App (Full Compilation!)

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
hello and welcome in this first lesson I want to answer the question what is Swift ey but I also want to make sure that you're very clear on how Swift UI compares with UIKit which is how we used to do things and how we used to build user interfaces before Swift UI I'm also going to go over the advantages of Swift UI and also its current limitations don't worry though this video isn't going to be all talk I'll show you practical examples and we'll also get into Xcode 11 and I'll walk you through how to build a demo Swift UI project so you can get your feet wet all right let's get started hi my name is Chris and this is the first time you're here welcome to code with Chris where we teach beginners how to make apps now before we dive in I have a quick question for you when do you find time for learning new things this is especially relevant for me right now because I'm spending a lot of time learning Swift UI and personally for me I find mornings to be best so let me know how you learn best when you find time to do that in the comments section below and if you wouldn't mind on your way down there please give this video a quick like I really really appreciate it it really helps with the YouTube algorithm and getting more eyeballs on this video so I really really appreciate it thank you so much alright with that said let's talk Swift UI to understand swift UI and fully appreciate how much easier it makes building user interfaces let's compare to how we used to build user interfaces with UI kit using UI kit we're able to use code to build the UI programmatically but we have to be very literal and precise about exactly what happens for example let's say we wanted to put a text label in the center of the screen here's how that would look if we did it programmatically with UI kit all right so the first thing we're going to do is we're gonna create a label element to add to the view so let's add a common here and I'm gonna declare a new constant we'll just call it label and we're gonna create a new UI label element and assign it to this constant next we are going to set the text to hello and then we're also going to set this property called translates our oversizing mask and constraints to false and if you're not sure what the auto-resize a mask is it's something from an old layout system before Auto layout that worked on something called struts and Springs where you describe which sides or edges the element should hug and how it should compact and expand depending on how much space there was and when Auto layout was introduced we then we were able to specify the rules which we call constraints on how to size and position things and so what it would do it it would try to change that Auto resize a mask and translate it into Auto layout constraints if we don't set this to false it's going to try to create by default these constraints for us which will interfere with the exact positioning and sizing that we want to achieve so we have to remember to set this to false okay so what we also have to do is remember to add this label to the actual view because if we don't the label is actually not visible and it's not in the view hierarchy so we're gonna say view dot add a sub view and we're gonna add the label and now the label is on the view and there is no positioning for it yet so it might not even be visible so here we got to create some constraints which is going to describe how to position this label inside of that view so we're going to Center it on the screen I'm going to create two constraints I'm gonna just create this first one and I'm going to assign it to a constant called center X all right so when you're specifying a constraint you're basically relating two things together so we're going to relate our label to the view and we're going to make them both have equal Center X's and that is basically centering it horizontally and so we want the label to be in the middle of the view so the first item is labeled the attribute that we want to define this constraint for is the center X and that's basically the center point of the we're going to relate it by equal and to which item we're going to relate the label to the route view remember so we're going to specify the view and we are going to relate it to the center X attribute of that view multipliers one and constant is zero and the multiplier constant just lets us exactly what they mean to specify either a slight offset with the constant or a multiple with the multiplier right there okay so now we've got to do the same thing but for the y axis and this is going to center it vertically rather than just typing all of that out again I'm just gonna copy and paste this guy and just change the center X to Center Y so now we're relating whoops moving too fast there now we're still relating the label right to the view except we're making both of them have the same center Y and then lastly don't forget to add these two constraints to the view and this is one distinction that also a lot of beginners have trouble with is that let me just finish this before I explain it so I'm going to add the center X and center Y constraints to the view now the thing that confuses beginners sometimes is that in order to position the label you actually have to add the constraints to its parent container which is the view because the the label is inside of the view right however if you're specifying sizing constraints for the label then you're going to be adding those constraints to the actual element so you would add it to the label positioning ones go in the parent container whereas sizing ones go on the actual element so that's one distinction that you have to do otherwise it's not going to work so let me just run this and you can take a look at what we get so we did all of that typing just to put a Hello label in the center of the screen and the other thing is that the order of your code statements here actually matter because for example in this line of code we added the label into the view but if took this line out let's say we forgot to add it all together this would crash because you're trying to relate to items like the view and the label where one of the elements is actually not in the view so you're not able to draw that relationship right also if you had remembered to add the label to the view but you added it down here again it would crash because this line of code right is actually applying the constraints and because the Train says looking for the label but the label isn't in the view so you actually have to make sure that the label is in the view up here before you try to you know add any sort of positioning constraints for that element so these are all things that can actually go wrong so that's programmatic UI and UI kit but that's not the only way you can build user interfaces with UI kit you can also use interface builder and storyboards and here's how that would look like so to achieve the label in the center of the screen using storyboards what we're going to first do is open up the object library up here and then we're going to search for label and then we're gonna drag it and drop it into our view right there so we've got our label on the screen however it's not positioned at all we have to add some constraints to it so make sure that you have your label highlighted and then open up this add constraints menu and actually we want this alignment constraints menu beside it instead you're gonna want to check off horizontally and vertically in container and then say add these two constraints and just like that we've got the label in the center of the screen the last thing to do is to change its text so highlight the label here in the document outline and then let's type hello and let's run our app and then we're gonna see it in the simulator with the label in the center of the screen now that might have seemed easier and faster versus programmatic UI but using storyboards brings about its own set of challenges I have an entire video comparing the programmatic UI approach with the storyboards approach right there however whether you're using storyboards or no using uikit requires you to be very explicit and precise about exactly what you want the layout system to do this is known as building your UI imperative lis this is very different from Swift UI which is a declarative framework now let's take a look at what that means with Swift UI you don't have to specify every single little detail because the system handles a lot of that grunt work for you you simply have to describe to the layout system what you want and it'll go and do that for you in the WWDC video describing and introducing Swift UI they used a great analogy that I still use today to describe the difference between Swift UI and UI kit UI kit is like you talking to a friend through the phone and giving him very precise and explicit instructions about how to make an avocado toast properly whereas Swift UI is like you telling an avocado toast expert what you would like and then just having the expert go and do it for you with Swift UI you don't need to worry about every single little detail such as whether or not the button is added to the view let's use our previous example about putting the label in the center of the screen and let's see how much easier it is to do with Swift UI now here what I've got is a default just out of the box Swift UI project and what we want to do is put a label in on the center of the screen however the default project that you get start with is already a label in the center of the screen so before we dive into how we create that let me just give you a quick walkthrough of how you create user interfaces inside Swift UI basically you're writing code on the left hand side here and on the right hand side you get a preview now you can also launch it in the simulator to see what your UI looks like but this preview is pretty handy so let's dive into the code here this text element is all you need to write in order to have this label in the center of the screen and just to make it the same as you know all of our other demos we're just gonna have hello so there you see it if I run the project you're gonna see that we get the same thing with our two demos using storyboards with UI kit and also programmatic UI with UI kit see now the notice that I didn't have to add any constraints I didn't have to tell the system to put the text in the middle of the screen all I indicated here was that I wanted a label that said hello and the layout system automatically made some assumptions of where I wanted to position it I could manually add some rules or specify where I wanted to position and maybe I want to add margin here or that side you know some padding or I wanted to push it all the way to the top of the screen but because I didn't specify any of that stuff it made an assumption that I wanted it in the center of the screen which is logical to me and that's what it did you see what a difference that is compared to UI kit so which is better and why would we want to use swift UI well let's just get one thing straight right off the bat apple says Swift UI is the future of iOS app development and that's that you either get on the train or you don't same thing happened with Objective C and Swift now you might argue that Objective C can still be used today but you have to agree with me when I say the large majority of people have either started with Swift or they converted to Swift and they love it and I predict the same thing is going to happen with Swift UI and UI kit even though it might take a couple of years luckily for us and for future iOS developers Swift UI does seem like the way to go and I'm excited to go all-in however there are a couple of things that are preventing me from doing that right now though number one Swift UI apps can only be run on iOS 13 and above now that is kind of a problem now because not everybody is on iOS 13 however as time goes on and they release iOS 14 15 16 everyone's going to be upgrading and this is going to be a non-issue another problem that is going to be solved by time as well is that right now Swift UI doesn't come with as many out-of-the-box controls as we're used to with UI kit a lot of the major and useful and common ones are there right now but there are also a lot of third party controls and libraries for uikit that right now just aren't available in swift UI this makes it hard to go all in a hundred percent Swift UI but luckily we don't have to because you can actually use UI kit controls on top of a swift UI app so I think for now that's the way to go Swift UI is still in its infancy it's going to take a few years for it to mature but there's no time like the present to get a head start and start learning it now now let's dive into Xcode 11 and see how you can start building a swift UI app all right now let's start a brand new Xcode 11 project so I can walk you through how to start a new swift wide project as well as some of the different parts of the Xcode user interface that has to do with working in Swift UI alright so let's go ahead and create a new Xcode project we're going to choose a single View application and what's going to matter is what you select down here for a user interface make sure it's set to Swift UI if that's what you want to work with or set the storyboard if you want to work with UI kit all right so let's indicate that this is just a test I'm just gonna call this with UI test you can put anything for these other properties make sure that the language is set to Swift leave these unchecked and go ahead and click Next and let's just save it so it's going to create that project there and before we dive into this content view that Swift let's take a look at what we have on the left-hand side now if you're coming from working with UI kit and storyboards and stuff like that in Xcode 10 or 9 then you will notice that instead of just an app delegate we also have a scene delegate now essentially the responsibilities that the app delegate was taking care of has been split into both an app delegate and the scene delegate and the reason for that is because with iOS 13 and now the iPads getting bigger there is multiple windows support and that means that potentially your app could be running multiple instances of itself simultaneously so the app delegate is still in charge of the overall app life however the scene delegate handles all of these different windows potentially you know two different windows housing your app simultaneously next up you'll notice that we have much of the same elements that other files I mean you have the asset library you have the launch screen you have the info.plist but we don't have a view controller anymore what we have is a Content view and this file is basically where you're going to specify your user interface for a single screen in your app so let's take a look at the code inside of this content view you can see that you kind of have two different struts here right and then on the right-hand side you should see this preview pane if you don't let me just first go through how you hide and show this preview pane because it's actually very useful so you might have something that looks like this where it's just the code editor but if you click this editor options button here you're gonna see that you can select canvas so this is your preview canvas it actually gives you a preview of what your user interface looks like on this side so if you click resume what it's going to do behind the scenes is it's going to launch a simulator it's going to compile that code that you have and it's going to show you what that preview is now what's really cool is that you can change this preview to show you what you need by default you know you get this device frame here and yet your UI here but what's actually happening is this block of code here called content view previews this code is what is generating the preview here on the right-hand side it's just for development and debugging purposes this code that I have highlighted here doesn't affect your production app it doesn't affect the functionality of your app it's just for generating previews here on the right-hand side if you wanted to see two of these guys you could create another instance of the content view and put it in a vertical stack or something like that so you can have one on top of each other or you can does device frame maybe you want to see it in an iPhone 6 for some reason or you want to see a landscape orientation you can add all sorts of modifiers or maybe you want to zoom in and you only want to look at a specific element on your screen you could do that as well so this chunk of code right here is to modify your preview on the right hand side this struct here this is your actual user interface code and you can see here that this class is called or structures called content view and it returns a view and then you have a body property that returns to some of you now some view just means that it could be any type of view because it doesn't know what your view is going to be but it at the end of the day it's still going to be a subclass of view and then in here you have your various user interface elements now right here we only have a text label but what you can actually do is open up the object library and you can as long as you're in this tab right here because there's a couple of different ones as long as you're on this one you can actually drag the different elements as code into here now we're going to get into different elements and different layout containers in the next lesson so for now we're not going to dive too deeply into these different elements because I just want to give you an overall feel of how the user interface looks like for Xcode 11 and Swift ey now you can see here that as soon as I change something it said that the automatic preview updating is paused so it's not reflecting automatically what I type here all right when it maybe I make a change there if it's not updating here on the right-hand side all you need to do is click resume and that's going to recompile the code and then you're going to get an updated preview on the right-hand side the other thing you can do is also preview on your device that's what this button down here is for or you can do something called a live preview if you click that this is going to be constantly monitoring the changes that you make on this side so that when you make a change here it slows down a little bit but it detects the changes and it shows you the live changes here on the preview pane without you having to go hit resume all the time you can see here it takes a while for it to happen so you might not want to have that on all the time especially if you're into a long session of coding before you actually want to generate another preview or update the preview now there are some other interesting things you can do here on the right-hand side of the screen so you can actually modify things from this side it's not just editing the code on the left-hand side for example if I hold down command and I click this let's just get out of live preview first I can stop that if I hold down command and I click this guy you can see that I can do different things with it and we'll get into what these different elements are I just want you to know that you can interact with the preview pane in order to modify the code on this side so that's pretty cool you can still build your UI visually at least a bit of it and then these modifiers here see I've selected that text element and I can change the font I can change alignment and I can change padding and when I change these things in this sort of visual way it actually changes the code right so you have an option of how you want to edit and build your UI so you know I can specify numbers here and you can see here it's changing the code now if you know if you're very well-versed with the Swift UI code and syntax and you've been working with it a long time obviously it's going to be a lot faster for you just to type it all out but you know it's it's really cool to be able to do it visually as well so that you can see how it effects the code and like you saw before you can actually drag these elements straight into the code like this so I think it's really really awesome so I hope that gave you a good feel for Xcode 11 working on a swift UI project and where all of the different things are if you have time I'd highly recommend you to fire up Xcode 11 yourself start a brand new at Swift ey project just like we've done here and just fit all around in the next lesson I'm going to introduce you to a few more Swift UI elements so we can start building some cool layouts hello and welcome in this lesson I'm going to show you how to use a few more user interface controls and layout containers so that we can actually build a user interface all right let's dive right in so here I've got a basic swift UI project let's first go through the image element and this is what you use to display image assets in your project let's go ahead and add some to our asset library so go ahead and click that if you have your own images you can go ahead and add that if you don't check in this description below to grab these images which I have right here I'm gonna go ahead and click drag them all like that so it's just an apple a doughnut and a lemon and take note of the asset names all lowercase both doughnut and lemon because we're going to need to refer to these asset names and we're gonna change this text label element actually we're just going to erase this right now and we're gonna add an image element and there are a couple of different initializers you can use the one we're going to do here is called name and you just pass in a string indicating the name of the image asset that you want so we can do apple let's go ahead and hit resume there so that is how easy it is to display an image asset on the screen let's go ahead and change it and there you get a donut now let's take a look at the button element because you do want to add some user interaction to your app let's go ahead and delete that and let's create a button now this button initializer has a couple of parameters which you have to add two actually so one is action this block of code that you're gonna add in here will indicate what the button does when it gets tapped in the label right here this block of code is going to describe what the button looks like so you can put a text label in there to represent the button you can put an image or anything you'd like there so let's go ahead and open up the action and for this we're not going to go into how to write code for the button action just yet because that's going to come a couple of lessons later but for the label what we're gonna want to do and it actually just takes that it takes that parameter out and opens up a trailing closure inside this trailing closure you can actually put different elements that you'd like for example I want to put a text label that's one that simulator and then you get a button that has this text label as the button or you can put an image like let's say that donut that we had so let's go ahead and do that and you're gonna see a donut for the button now it's all blue its tinted blue because that's actually the default I guess tint or foreground color for buttons if you are going to use an image as a button then you actually have to set a rendering mode modifier here and we're gonna get into modifiers in the next lesson but right here is kind of a little preview of that so we're gonna select original and modifiers just very quickly is something that you can use to change the look behavior or the position the placement of the element essentially it modifies the element I don't want to get too much into it because we're going to cover it in the next lesson so then this is how you're going to use an image as a clickable button now you'll notice that every time I'm showing you an element I am deleting the existing one and adding a different one and the reason for that is because if you try to add two elements onto your user interface like this you try and run it you're going to get an error because this body right here it expects a single view back now the way you're going to have multiple elements in your user interface is that you're going to have to use layout containers to group these different elements together and have a single root element that satisfies this return type right here so let's go ahead and talk about our first layout container which is something called AV stack and if you used stack views before in UI kit this is exactly what ad stack is and Beast for vertical so let's declare a new V stack and actually I'm not gonna declare it this way I am going to create a new V stack object so that I can show you what sort of parameters you can pass in so for example you can pass in an alignment by default everything inside the V stack will be aligned to the center so I'm just gonna go ahead and hit I'm just going to do Center and spacing allows you to indicate how much space you want to put between all of the elements inside of the V stack so maybe by default put 10 20 and then the content here this closure if you open it up its gonna turn it into a trailing closure and take it out of the parameter list in here you're gonna put all the elements you want to stack together so I'm gonna go ahead and take my button and my text label and put them in there and then we're just going to wait for that to update so here you can see I now I can put multiple elements onto the view I've got the text element here and I've got the button which is a really bad button because you can't even tell it's a button but I've got two elements on the screen and they're stacked one on top of another and that's what the V stack helps you with now if you don't need to specify in an alignment then you can and you don't need to specify spacing you can go ahead and actually just get rid of those those are optional parameters and you can just have the stack and then you can have the opening curly bracket and the closing curly bracket and then all of your elements inside and you can actually stack more things if you'd like so the other one which we we talked about was an image right and this is going to make it even more confusing because now you can't tell which one's a button and which one's just an image but this is just for example purposes now another one we have another layout container that we have is called the H stack and you guess that H stands for horizontal so now you can see automatically everything is side-by-side and again it has the same parameter list you can align things by default to the center but you can align it to the top or the bottom and you can also specify spacing now one thing I do want to point out is that even if we specify a parameter let's say top and let's say the spacing is 20 and the content parameter we already have which is right here even if I did that you can see that the text label now gets aligned to the top but if you were expecting everything to get pushed up to the very top you would be mistaken because the height of the stack view or even the general size of that I just said stack you didn't die the H stack the size of that it is only as big as it needs to be to accommodate the elements inside of it it's not going to take up all of the space on the screen on its own if you wanted to do that you can use another element called a spacer and this element is simply to take up as much space as it can now if I wanted to push my each stack elements here all the way to the top I don't add a spacer inside my H stack because remember inside an H stack everything is side-by-side so my spacer would just simply push everything off to the left there if I wanted to push everything to the top I would actually have to put a spacer underneath my H stack to take up all of that space so the way I'm going to do that is I'm gonna add the spacer element first and it simply looks like that but I'm gonna get an error now because again now I have to route views right I have an H stack and I have a spacer and this is expecting a single view well the easy way to fix this is to wrap everything in a V stack like that alright so opening bracket there I should I'll do it this way so it's a little bit easier to follow and I'll cut all of that and put it inside my V stack see then everything gets pushed up because here we have my H stack right as the first element in my visa and then the spacer literally just consumes all of the space that it can and so my V stack now I've got it highlighted you can see it as this blue outline it takes up all of the space now similarly my H stack is centered it only goes from here to here if I wanted to let's say push everything to the left hand side I could add a spacer inside my H stack so let's put it to the right of the button and once it updates you're gonna see my spacer is here it takes up all of the space that's available and pushes everything to the left now one thing I do want to mention about the spacer element is that it shares the space with other spacer elements in the same layout container so let me give you a quick example of this I'm just gonna get rid of all of this first I'm gonna put a text element and I'm just gonna say hello alright so if I just update that you can see hello and let's say I wrap it in the V stack and then I put another hello element and let's just have three so you can see that my V stack is right there in the center of the screen it's vertically and horizontally centered and it's got three hello text elements inside there see if I add a spacer at the bottom what do you think would happen right it would take up all of its space thereby pushing all of those elements at the top what would happen if I add a spacer at the top here well this space would actually be divided evenly between the two spacers because they're both competing to take up all the space so they both get equal amounts now I can add another spacer here and now I have three spacers and you can see that the spacers actually consume the same amount of space so this one here this one here and this one here now if I add a fourth one they all consume equal spaces so this can be a neat way to Center elements and make sure that that they're spread out evenly and that things look really nice and proper now before I leave you with a quick exercise I want to show you one more layout container and that is the Z stack or Zed stack as we say here in Canada so I'm gonna change this v28 set and now it looks like all of our elements are gone well actually what a Zed stack does is that it puts elements on top of each other so if I change the text you're going to be able to see this reflected let's see this is the very back this is the middle and you can see it's 30 get jumbled and this is the front so you can see things are just laid out one on top of the other so this is what Zed stack is for it's good for putting let's say a background and then elements on top of a background right I could change this very back label to an image and let's say this week is gonna be the lemon and then it that way it's I feel a little easier to illustrate for you let's say I have the Apple in the middle and let's say I have the donut in the front so you can actually see that the things are stacked on top of each other now oh I forgot to change this to an image element there we go so the sad stack is really great like I said for putting an image as a background and then having elements on top or some graphic elements inside of your app might be comprised of several smaller image assets and you can use those adds back to stack them together to create the overall look and feel that you're looking for all right now that you'll know about these several layout containers and elements I'm gonna give you a quick exercise for you to try to achieve all right so here's the exercise it doesn't matter what graphic images you used but I want you to create a three by three grid with everything evenly spaced so you'll notice that every single row there is equal space in between each row as well as from the bottom of the screen and the top of the screen and also for each row every single element has equal space in between them here from the left edge between these elements right here and also from the right edge I highly encourage you to try it out it's going to reinforce what you learned in this lesson in the next lesson I'll show you how to use modifiers to well modify the behavior appearance and position of your elements hello and welcome in this lesson I'll show you how to use modifiers on your elements so that you can really fine-tune how your layout looks and behaves alright let's do it now here I've got a basic swift UI Xcode project with a single text element saying modify me I'm going to change the appearance behavior and layout of this text element to demonstrate how modifiers work now there are actually two different ways we can go about adding modifiers to this text element number one is by directly typing in the code into the code editor on the left hand side but number two which is the way that I'm going to show you first is to do it visually through the Xcode interface and the reason why I'm going to show you this way first is because by doing it visually through Xcode it's actually going to generate the code and update the code editor and then we can go and talk about that code and then later on I'll show you how to just type it in directly alright so what we're going to do here is on the right-hand side open up the inspector pane if you don't have it this button here oh and one thing to note is that in order to do it visually through Xcode you have to be able to see this canvas which means that you need to be running Mac OS catallena or above so if you can see this preview then you're gonna be able to do it visually if not then just sit back take a look at what I'm doing and as soon as I start doing it through the code by typing it out you'll be able to follow along as well alright so let's go ahead and select the text element here and then in the inspector pane under this attributes inspector you're going to see all of these different attributes that you can modify on this text element this is very much like using uikit and storyboards right alright so we're gonna select modify me this text element here first we're going to change the weight I'm gonna change it to heavy and you'll instantly see it reflected in the preview but also the code has changed in the code editor all right so let's just quickly take a look at what happened there and it actually put it on a second line but if I were to just you know close that do that it starts to look very familiar right it looks like you're calling a method on the text object or a text element which is exactly what you're doing you're calling this font weight method on it intercepts a single parameter indicating the actual weight and we're passing in heavy so that's essentially what a modifier is you're just calling a method on the Swift UI element and the reason they put it on the second line like that is because as soon as you chain together more and more modifiers it's going to get really messy if it's just in one line which I'll show you in a second and that also alludes to my second point is chaining together modifiers how do you modify this text element a bit more let's show the canvas and let's show the inspector and let's try to add another modifier to this element so click on this guy let's change the color to purple I mean she's purple there and it's changed the code again and you'll see it reflected right there but let's just take a look at that so you can see how this list is neat and tidy right I can clearly tell that that's a text element we've modified it in terms of the font weight and then we've called another modifier to change the foreground color if it was all in one line you can see what a mess that looks like it's really hard to make out what sort of modifications you've done on it right so that's why you should indent it right before the dot in this dot notation and then you're going to get a nice list of modifiers all right so and one thing to note is that if you were to do this programmatically you would essentially be typing it out right so you would instead be doing this font weight and then you'd put in heavy and you'd hit enter and then you'd go foreground color dot purple that's going to give you the exact same result I just wanted to show you doing it visually now we've fight the appearance of the text element but I alluded to modifiers being able to change the behavior and also the layout of the swift UI elements as well right so I'm going to show you that let's change the behavior of this text element let's let's you know what because it's only a single line it's kind of hard to see but I will centre align this text and it's added a modifier called multi-line text alignment and passed and centered so that's gonna if I had more text it would be centering that text maybe if I just add a little bit more you can see that right centering that text all right now in terms of changing the layout you know one thing you can do is add padding let's say you wanted to add some padding to the left and right side so there is a modifier for that let's do it visually first and you can see what the code looks like I'm going to enable left padding and right padding and you can see that the padding actually that's not the best example so why don't we just do left first so you can see that it's called a padding modifier and it's passed in the leading edge because that's what I want a pad and by default it pads it by 20 points so you don't need to pass in any parameter but if you want it to padded by a specific amount right let's say I wanted to pad it by 50 like that you can see that it does accept the second parameter indicating how much you want to pad it by and if you wanted to pad a couple of different edges you can let's say do the top as well and now instead of just passing and leading you're passing in an array with all of the edges that you want to add this 50-point padding to so you could see that now what was interesting is that when I did just left and right it changed the parameter to horizontal meaning I guess that's just a default that includes left and right all right so now you might be wondering you know modifiers are great but if the modifier like are these all the modifiers that I can add to the text element and the answer is no there's actually a lot of modifiers that you can add to a lot of different swift UI elements some are unique to the but some are common to all views which is essentially what a swift UI element is if you hit this drop down here you can just look at all of the different modifiers the ways that you can change the look the behavior in the layout of the element now the more you use these the more you're just going to know it by heart so if you want to do something with the element you're not sure how to do it I would look through this modifier list first and see if there's one that looks like something that you need play around with it and and then over time you will know what's available there's no point in trying to memorize this or anything like that alright so what we're gonna do now is I'm going to show you a little bit of a more practical example I'm gonna delete this element and I'm gonna add an image and we're going to add some modifications to it to make it look more like the stuff that you see in apps these days so let's actually before we delete this text element let's go ahead and add an image asset into our project now I've already got an image asset prepared and you can find it in the the resources for this project it's one of the welcome lessons that links to the folder where you can download all of the code and assets and stuff like that you're going to find this pink building asset under this lesson now you don't have to use this you can use any image you want there are no size restrictions or whatnot it's just the demonstration so I'm gonna go ahead and add this pink building to my asset library and I'm gonna go back to my content view now and I'm going to just delete the text and add an image element and pass in a pink building let's hit resume so we can take a look at the actual photo and there it is now this is actually a small window of the larger image because Swift UI doesn't assume that I want to fit the image into the view so it displays the image at its native size centering it now those are the assumptions that it's made but if I want it to fit the image into the view I can add a modifier to the image called resizable now this one you're probably going to be using a lot and by calling this modifier on an image element it lets the layout system know that you're ok with having that image resized now by default the aspect ratio is maintained so it it maintains the aspect ratio and it tries to fit that image within the view without scaling it but what if I wanted to let's say stretch this image and use it as a background well I can do that first I'm going to call another modifier called ignore safe area and the safe area just for review because you learned this in my beginner series and stuff like that is this area here this is called well the safe area is where you see the image and now the not safe area I guess would be all of the white parts and the not safe area is are basically places where potentially it could get covered or it could get blocked or there could be text overlaying it so you don't want to put elements there but for a background image you might want to so there is a modifier called ignore well edges ignore safe area and then you pass it in all the edges that you want to ignore the safe area for so when you do that it just you can see the image go into the safe area now now just in case you do want to change the aspect ratio I'll show you another modifier called you guessed it aspect ratio and the content mode you can set it to fill or fit by default it is set to fit and basically that means to maintain the aspect ratio but still fit the image inside the view fill will make sure it tries to cover all of the space while still trying to maintain that aspect ratio all right so what I actually wanted to do with this image though I'm just gonna go back here I wanted to make it sort of like a floating card because you see a lot of images like that these days so what I'm going to start by doing is just adding padding so instead of specifying in sets specify how much padding I want I'm simply going to be calling padding when you just call the padding modifier without passing any parameters in it assumes that you want padding on all of the edges at 20 points so that's what it's giving me right here and then next I am going to next I'm going to actually organize my modifier list because I'm going to be adding a lot they hit enter I'm going to add a second one and I'm gonna call corner radius this modifier will give me rounded corners and I get to pass in what sort of degree of rounding that I want now take a look at this I called this corner radius right expecting some sort of rounded corner but clearly it's not working and I know my view has been updated because there is no question here asking me if I want to resume the preview so this is the latest state but where are my rounded corners so this part is really interesting because the order of the modifiers that I have added actually matters and that is what the problem is right now you see let me rearrange this if I add the corner radius here and then I add the padding you can see that I get the result that I want so what's going on here let's let's illustrate the order actually matters so here I've removed the padding and I've applied the corner radius right so you get this sort of result and then you're adding the padding on top of that result all right and it pads it but what about the other way around like what we did if I did padding first I get that padded image but then when I add the corner radius like that it's actually applying the corner radius to that part right which essentially is just my padding so it's adding the corner radius to my padding that's why you don't see the actual image here having rounded corners so take note that the order you apply these modifiers in it actually matters so what I actually want to do is to do that so apply my corner radius first and then add padding to the whole thing and then to take it a step further I want to add some shadow some drop shadow to this image and with swift UI is really easy because there is a shadow modifier all I have to do is do that you can see a slight shadow being cast under my image is pretty diffused but there it is there well maybe if I didn't set the radius so much I would see a little bit more of it all right there we go next up I'm also going to put it in a V stack and let's put the text right under it it's gonna have my text element this pink building is totally amazing and we're gonna add some modifiers to this guy so much like before we had the heavy font weight or we're also going to have the foreground color and let this time let's choose pink and we're also going to set the font itself and I'm going to change the font to these are some of the presets I can do a large title type of text so you could do that and then you can do alignment multi-line text alignment and I can Center that and then lastly I can do a shadow I want to show you a different shadow method see this one where you can set the shadow color and you can also set you can control it a little bit more so you can control which way the shadow is going so I'm going to say the the color is going to be red the radius is going to be I'm gonna use a really tight radius so it looks like I'll show you what it looks like so it's not diffuse ah that's really hard to read okay let's just use black alright so it looks something like that so by having a really hi radius it's not diffused it just doesn't look like it's a blur shadow it's a really sharp shadow yeah all right so now that I've showed you some modifiers and how easy it is to use I have a challenge for you now if you look under the challenge folder in the resources for this lesson you're going to see that you have all of the assets that you need to try to recreate this layout now just to give you a hint you're going to need to use what you've learned in this lesson as well as the previous lessons on layout containers and those sorts of elements there in order to achieve this effect I highly recommend that you try it out because it's really going to give you that extra practice and solidify your understanding of modifiers all right in this lesson you'll learn that each Swift UI element can be configured by calling methods on them you can do this to change how they behave how they look and also how they are positioned in the next lesson we'll talk about what state properties are and how your UI can automatically change and adapt according to what the state properties values are all right I'll see you in the next lesson hello and welcome in this lesson I'm going to teach you all about state properties and how to use them so that when the values in these state properties change your apps user interface will adapt and change and update automatically all right let's dive in state is a very easy concept to understand essentially it's a piece of data that the user interface depends on let's say you're looking at a photo and this app has the ability to heart a photo that you like so you might have a state property that keeps track of whether this photo is hearted or not by the user if the state is set to false then the user interface will display an empty heart if the state is set to true then the UI will display a filled heart so let's go into Xcode now and I'll show you how easy it is to implement this now here we have the Swift UI project from the previous lesson and we're gonna build upon this to demonstrate state properties if you didn't build this project from the previous lesson not to worry you can find this starter project in the resources for this lesson however if you did build this project from lesson 3 then you can go ahead feel free to use yours let's describe what we're gonna do in terms of state properties here so I'm gonna put a heart button here between the image and the text that the user can tap on to toggle whether they like this photo or not and depending on that state we're gonna have that heart icon change to a filled heart or an empty heart to reflect that status and we're also going to have a count in in terms of the number of likes or hearts now let's start by adding the heart icon in between this pink building image and the text so here I've got my V stack and I'm gonna do that right here now rather than adding my own image assets for the heart we can use something called SF symbols without getting too much into it because I want to dive deeper into it in the next lesson I'll just say that SF symbols is a collection of icons and symbols that you can use it comes packaged with iOS 13 and you can just use them they're very helpful so let me you gotta take it at face value here and just copy what I do in the next lesson I'll dive a little deeper into how you use them and what they are and what you can do with them alright so you start with an image but we're gonna use the system name or named system name initializer and we're gonna pass in the name of the symbol so I'm just gonna say Hart and you're instantly going to see that heart icon there that's just part of the system I didn't have to add that as an asset now there's a different one called heart fill and it's essentially the same icon but filled in now this is just a static image icon right here we want to make this dependent on some sort of state right so let's go ahead and declare our first state property we're gonna do it right under this content view struck here before the body and the magical keyword we use is at capital S state and that's going to indicate a new state property use the VAR keyword just like a normal property and you give it a name I'm gonna call this is hearted and I'm going to set it to false now one thing that you want to do it's a recommended practice is actually to make it a private property and the reason for this is because state properties are really meant to describe the state of this particular view which is content view if you have a piece of data or a property which you want multiple views to depend on there are other mechanisms to do that that wouldn't be using a state property so we can get into those later on in the series but for now we're looking at state properties and the reason why we make it private is just to reinforce the fact that it's only accessible by content view and that's what happens when you use this private key word access modifier so that's why we put private there just to reinforce that all right so what were we doing here okay so we've declared our state property is hearted and we're gonna make it this icon depend on that very simply we're just going to use an if it is hearted you know it's true then we're gonna display this heart let's see what happens here because it is set to false so this is not going to trigger if you hit resume you'll see that it disappears because this is false so it's not gonna happen have this image element here but if I add an else clause and I show an empty heart instead when that is false then we're gonna see an empty heart right because this state is false right so it's going into this branch and showing this so let me set this to true and resume it and it is filled in now that's not too amazing alright because I'm manually changing the stay here through code it's basically just toggling between these two branches of the if statement but however let's say we change that heart into a button I'm going to declare a new button so let's go ahead and do that and for the action we are going to toggle the is hearted property when you call the toggle method in case you haven't used this it just toggles it between true or false so it changes that state now for the label here I'm gonna get rid of this and for the label of the button it's just going to be this code right here so the the actual image of the button is going to depend on the state all right so now let me just run this project so that we can play around with it in the simulator another thing you can do is actually use the live preview but I'm already building it right there all right so we've got our UI here it is hearted if I tap on it it toggles the state property is harder to false and this image of the button is going to change by itself see I didn't have to manually tell the button to change its image all I had to do was toggle the state hit it again it toggles the state and the image of the button changes automatically now this is one illustration of using state as a boolean but state can also be an integer it can it can be anything so I'm going to show you another an example of a state and I'm gonna call this num hearts I'm gonna make this 999 and I'll set this back to false okay so the now we're using state as an integer and so what I want to do is show the count beside the heart and we're gonna do here is we're gonna declare a horizontal stack I'm gonna put the button inside of it and then we're also going to have the count so I'm gonna have a text which is going to be the num hearts the problem is that num hearts is an integer and in order to display it inside a text element I'm gonna have to convert it to a string so let's go ahead and create a string from that and I'm gonna hit resume and we should see the label right beside it all right let me just try running this project all right so I've got nine nine nine nothing happens obviously because we haven't added the code yet but what if I add the code to increase or decrease the count whenever I toggle it so I'm going to change that code right here so when I toggle it I'm gonna add some additional code I'm and it's starting to look pretty messy so actually I'm just gonna reinvent everything I'm gonna select everything go into editor go into structure and hit re indent if you didn't know about this this is the shortcut key or the menu item tap on that is just going to make everything nice and tidy for you all right now we're going to say you know if self is hearted then we are going to say num hearts is plus equal one it's going to add one to the number of hearts else we're gonna minus one and the reason for that is because you are unharmed so you're removing you're removing a vote essentially so let me run this project again in the simulator alright so when I tap on this now it's actually going to toggle this to true and it's going to increase that number of hearts to a thousand and we're gonna see that this text increases automatically in UIKit in order to do this I would have had to set the text property of this label to a thousand you know to the updated camp but in Swift UI because we're using state properties all I need to do is update the property and all of the pieces of the UI that depend on those property that are listening to changes for those properties they just update themselves automatically that's how great and easy that is to do now I have a challenge for you guys and that is to change this text down here if the image is hearted then I want you to just have this amazing text that we have here but if it is not hearted that I want you to use some basic text or some very sad pathetic looking text use some small font or something like that but if it's hearted then we're gonna make this bold pink and amazing like I think this is pretty pink bold and amazing but you can make it even more if you'd like just to get some extra practice in with using state properties so in this lesson you'll learn all about state properties and how you can have your user interface update automatically when the values change in the next lesson I'll show you what sf symbols are and some of the cool things that you can do with them thanks for watching and I'll see you in the next lesson hello and welcome in this lesson we're going to talk about SF symbols a large collection of system icons that you can use in your iOS 13 apps not only are they very handy they also come with a lot of additional benefits which I'll demonstrate for you in this video all right stay tuned so here I have a basic swift UI Xcode project and all I have is an H stack with an image and text element inside of it the text says like and the image is one of a heart now keep in mind that I don't actually have an image asset of a heart in my asset library in this project instead I'm using the SF symbols icon framework which I alluded to in the previous lesson so let's take a look at the Apple human interface guidelines I'm just going to pull that up right here and take a look at what exactly are these symbols so SF symbols are a set of 1500 icons and symbols that you can use in your iOS 13 apps now Apple design these symbols to play really nicely with the San Francisco system font if you're unfamiliar with what this font is it's essentially the default font that you use in your app so if you're not using any sort of custom font then you are using the San Francisco font and as you can see using an SF symbol alongside that font looks really neat and tidy everything's aligned and arranged nicely whereas if you had supplied your own heart image you might have to play around with the sizing and alignment just to get it to look in line with the text so the other thing that is a huge benefit to using SF symbols is that it behaves like a font as you can see here for each of these symbols there are different weights like ultra light thin light regular all the way to black there's different like line thicknesses and sizes as well and these symbols are vector based which means that no matter how large or small you scale them they're going to be really sharp and the fidelity is going to be consistent just like the font so let me go back into Xcode and demonstrate for you so you can visibly see some of those benefits I'm talking about so for example if I want to change the the font that I have and I want to add a font modifier maybe I want to do a large title type of font as you can see it changes the text element as I expected but it also changed that image element that SF symbol had I used my own supplied image graphic that wouldn't have done anything this modifier I mean or let's say I want red font red text if I change the foreground color to red that affects my SF symbol as well so that's really nice and then for my next demonstration let me just remove this red color because I mean you're going to be able to see a lot more clearly and then I'm going to run this app in the simulator let me just bring that over here and I'm not sure if you knew about this in Xcode 11 but there is a menu that you can bring up by clicking this button called environment overrides and this allows you to test your UI and test your app under different device specific conditions so things like whether or not the user is using dark mode or light mode what kind of dynamic type magnification are they using maybe they can't see the text very well so they have upped the magnification or the font size and also these different accessibility options you can see how your app plays nicely or not so nicely with them turned on so why don't we go ahead and try to turn on dark mode oops there we go now as you can see the text element changed to white because obviously black text on a dark mode you wouldn't be able to read it but what I didn't expect was that the SF symbol also turned light if you were to use your own supplied image or graphic asset you would have had to supply to one for the light mode and one for dark mode and then there's a way for you to configure it inside the asset library to tell the system which version to use for a dark mode and which version to use for light mode but if you're using an SF symbolize we're using here you don't have to specify any of that because it behaves like a font so you kind of get this for free which is really nice the next thing is that you have dynamic type so some people might have this huge magnification on to make sure that they can read the text your SF symbol scales with that so you can see that with an image not so much and then same thing with these accessibility options anything that you would expect to happen to your font you know your symbol will also play nicely with that so that is awesome and there are 1500 of these symbols for you to use and if that weren't enough Apple has said that you can actually export these symbols and customize them to your own so let me show you where we can browse these symbols and how you can export one to configure it or to modify it to your needs and to your liking so here is a link to the SF symbols app I've got it open right here actually it's a Mac OS app which allows you to browse all of the different symbols that are available in this framework and you can also choose the waiting and stuff like that and it's it's a nice way to browse all of the icons essentially and the way you use them is you take note of this name and all you have to do is specify this name let's say this one Mike dot circle dot fill and use the system name initializer for the image element and just pass that in hello is that again Mike Haddad circle dot fill and let's take a look at that alright so there you go that's how easy it is to use if you wanted to export one of these icons and use them as a template to build off of you can also do that so just highlight the one that you want let's say Mike go up to edit sorry file and export custom symbol template the shortcut key is command E so when you do that it's going to produce an SVG file for you which is a standard vector-based graphics file then you can save it somewhere and you can import that into your favorite vector-based graphics software such as adobe illustrator or sketch or what I like to use figma because it's free to use and get started with so that's what I'm going to show you here I have figma open I'm just going to drag and drop that Mike SVG file into here and then you can see all of the different weights so it might be hard to read for you here there's thin all the way light regular medium semi bold bold and then there's different sizes as well here and then down here in the lower left-hand corner there are some instructions and some some guides and that's how you can customize these well this is granted if you know how to work with vectors and to edit vectors right so that is another learning curve but for let's say a designer that knows how to create their own icons and modify vectors then this would be great for them now there are a set of icons that Apple has said you should not touch and you should use as is so if we go back to the human interface guidelines and you scroll down these symbols are for use as is and these symbols mostly have to do with Apple brands so they are they don't want you to tamper with brand logos or brand iconography which is understandable so you have things like airplay AR KITT iCloud FaceTime face ID stuff like that for these symbols you want to use them as they are for anything else it's fair game for you to export modify customize to your liking and use now before we enough this video there are a couple of resources I do want to mention that might make your life easier so this one is called SF symbols calm it's not by Apple it's made by a developer named Noah and it's a very easy way for you to find an icon that you need in case you don't have the mac app installed and let me just show you how that works so let's say I'm searching for that that looks like or sounds like the one that I need copy it and then simply paste it in here and just like that very easy so this is very handy there's another article from a Vanderley on SF symbols that helped me out when I was learning this and this is very handy to go through if you'd like to do that so yeah I would highly recommend that you use SF symbols where you can especially for places like beside button text or in buttons in menu buttons even in tab bars those are all great places to use sf symbols but keep in mind that the use of SS symbols there are some restrictions and maybe I should have mentioned this up front but it says here that you can't use SF symbols in your app icons logos or any other trademark related use however I think using them inside of your app is fair game so in this lesson you'll learn all about SF symbols and how you can incorporate them into your app in the next lesson we're going to start building our first swift UI app together a slot machine alright thanks for watching and I'll see you in the next lesson hello and welcome in today's video you'll use everything you've learned about so if you Y up to this point to build this Lots app believe it or not by the end of this video you'll have this app up and running all right let's do this alright guys here we go this is so exciting let's start our brand new Xcode project here and we're going to choose single View application and for the product name I'm gonna just call it a slots demo you can follow the rest of these settings but just make sure that your language is set to Swift and your user interface most importantly is set to Swift UI because that's why we're here you cannot be the rest of the settings as I have it here and let me just choose a place to save this I'm just going to save it on my desktop along with all of the other folders the billion folders that I have I also took a screenshot and while that's kind of starting up I want to talk about how this UI is constructed so the screenshot I took of the finished product and what's happening here you might think that this is a graphic background but it's actually not and I just noticed that this is kind of cut off here what's actually happening back there are two rectangles one obviously covers the whole screen that's the deeper yellow and then there's another rectangle on top of a lighter yellow that is rotated on an angle so the only graphic images in this app are these Apple icons and the cherry icons and the star icons this is actually an SF symbol which you learned about previously and those are yeah these are the only images these slots icons so why don't we start by adding those icons to our image assets I'm just gonna leave this screenshot right here so we can take a look at it when we need to so if you check in the description below this video you'll find the image assets that you can download so let's go ahead into the asset library and just go ahead and drag all of them there now I'm gonna actually rename some of these to cherry and star alright and next let's go into the content view and start building out our UI and let me describe to you kind of the main layout containers that we have so in order to have elements stack one on top of each other we use a said stack or a Z stack as you might call it so that's how we're getting the two rectangles for the background stacking on top of each other and then on top of that background we have a V stack which contains all of our main user interface elements so in that V stack we have this title which is essentially just an H stack a horizontal stack with an SF symbol text label and then another SF symbol and then this is a text label with just a rounded background color and here we have an H stack with three images and then finally we have a button down here and that all of those elements I just described are in a V stack sitting on top of the background so why don't we go and construct that so I mean I get rid of this text label right here and I'm going to create a stack I'm gonna call it as that stack whether you this is I'm Canadian in case you didn't know so I'm gonna create a rectangle right there let's that doesn't have any color we probably won't even see it so why don't we there we go I had a foreground color now for the actual color I am gonna create a new color and I'm going to specify the red green in the blue because I did this in figma where I picked a specific color and then you can kind of see the red-green-blue breakdown and so I'm gonna specify those values but I can't remember it off the top of my head but I have them written here so for red I have 200 for green I had 143 and for blue I had 32 so there we go there's our rectangle and we also want it to go to all the edges ignoring the safe area right so I'm going to say edges ignoring safe area and I'm gonna pass in all because I want it in all directions so there we go we have our first background now let's add a comment here first and I'm not really not liking the way that that's looking so just looks ok let me just go up here a structure and read and dent everything like that so it looks neat and tidy so let's do another rectangle and this one is going to be again the foreground color this one I also have a specific color so I'm gonna specify that and for this one the red is 2 to 8 the green is 195 and the blue is the 76 all right and I'm going to rotate it rotation effect and I'm gonna specify an angle so let create a new angle object and pass in 45 and then I'm going to specify ignore edges so it goes all the way to the end there we go all right so that's our background now we have our V stack right our main V stack that contains all the elements sitting on top of that background so as I described here in the first element in the side that V stack that is actually an H stack containing the star the text and another star so let's go and add our H stack here and I'm just going to add a title and then this is going to be like credits counter alright so let's do this first H stack what do we have we have an image and inside we actually have an SF symbol so let's fire up the SF symbols app and what I want to do a star so this is the one I chose star dot fill and so I'm going to close that and we're gonna use that star dot fill and it's blocked by default but I decide to set a foreground color of yellow so there's that image it's small now but we're gonna make it a little bigger in a second all right so I'm gonna copy this and paste it and in between there I'm gonna put a text label so this guy just said Swift UI slots now I made this fun bold so let me just see exactly yeah I did font weight of bold and foreground color of white so I used font weight and I passed it in bold but you can actually maybe just call bold like that that's cool foreground color and then let's do white so I guess bold has its own modifier but you could also do it like this where you pass in a font weight and then you can choose bold there's a couple more options here but I wonder if like heavy and black and light have their own modifiers too let's just double check light i guess cuz bold is so common that has its own modifier whereas if you wanted to use black or heavy or light or the other font weights you're gonna have to use the font weight modifier and pass in that specific one alright that's cool and then in order to make it bigger I added a scale effect of two alright so now it's looking a little bear it's in the center which is fine as we add more elements into our V stack that's it's gonna space out and then we're gonna take a look at adjusting all the spacing at the end let's just focus on adding all of our elements so the credits counter that's this guy right here so that was just another text label and for now we can just hard code this text here and we're going to make this an actual property or state property later so for this text I set the foreground color to black and I also set a background color now this background color I set to white but I also added a slight opacity to it so I actually only have to just take a look at what we've got here okay so we've got the white background okay and then I set an opacity on this of 0.5 and you see how closely it's hugging the text let me just zoom in a little bit like that so what you can do is you can add padding but here here's a good point to illustrate the order of how things go so I'm going to say all edges use the padding modifier and I'm gonna give it a padding of 10 so you can see that you know this blue outline is my text label and it indeed added padding but the background itself is still pretty small so what I needed to do instead is first apply the padding and then apply the background color to the whole thing and if I change the order like that you'll see that then I get the desired effect and then finally I added a corner radius of 20 and that's gonna give me that look right there like that all right next up is the main course here the three cards so I'm going to this was an H stack horizontal stack containing three images so we've got the first image and again I'm just going to hard-code the image here so we've got our first image here I'm gonna add the resizable modifier so I can resize this and I've shown you this in previous lessons in this Swift dy series before I'm also going to make sure that the aspect ratio is 1 and for the content mode I want it to fit instead of fill so it's really big now but we're going to add a couple more so let's add a background again I'm going to add a white background with a slight opacity 0.5 and finally I'm going to round the corner 20 so we get a sort of card like effect now let me just indent all of these things being very careful [Music] oops that was yeah there we go just want to make sure that that looks right there we go all right so we've got our image there and I'm gonna just copy and paste this so I need to mention here that in swift UI one of the guiding principles for view composition is actually breaking down elements into smaller reusable views and so I'm not gonna do this in this video because I just want to get this up and running in the next lesson I'm gonna show you and explain some of the guiding principles the one I just mentioned about view building and breaking down your views into reusable views as well as how dataflow is supposed to work in the swift UI and then we're going to come back to this slots app and we are going to apply those principles and improve the code refactor the code so right now I'm just going to copy and paste this three times just to make things really really simple so we can actually finish this app in one video now I'm going to add a spacer on the left and right of this H stack so that it's gonna create some space there and I could put spacers in between these images as well but it looks like you know they're together and I on a water screen I don't want them you know to fly apart because the spacers will take up an equal amount of space instead I'll just have margins on the left and right but keeping the three cards together okay so we've got our cards here and what's left is this button so we've got our cards this is the H stack and this is the button so let's create a button element here so we've got our button and where's my autocomplete there we go so we've got action and we've got the label so for the action I am actually going to just not fill that out yet for the label that's going to be a textile so I mean just the button I'm just gonna put to do and then here the actual visual representation of the button is a text field that says spin and let's add some styling to that so we've got bold and we've got a foreground color of white this is double check yeah with white and we have this pink we have a background color of pink I think the pink yeah okay and again I'm gonna add some padding to it but we got to do it before we set the background so you're gonna add some padding to all edges with the ten so see if it can actually reflect that all right I might have messed that up but let's take a look look let's actually run this in the simulator and see if the bill failed I might actually have to do something in here okay I think I messed up my let me just get rid of that button I think I messed up my curly brackets so you know it's actually launching all right so that looks good let's put our button back all right up here let's declare some stuff so we have accredits right private VAR credits equals a thousand so we can start off with that and I do want this to be a state property because we're going to be deducting credits and I wanted to appear automatically so in here I'm gonna erase that hard-coded text and I'm going to put credits and I do have to convert it to a string because this is an int all right you see that so I'm going to do that right there and now I just want to see if I can say self dot credits plus equal one just want to put some code in there and see if that's what was missing oh sorry it's this it's this right here background I have to specify that it's a color pink because this expects a color already but the background expects any this could be anything you could be putting an image in there or anything so I guess I have to specify it like that alright so going back to customizing our button here first so we have a padding of ten right here and then we set a background but to me it doesn't really look like let me just update this UI there we go that's what I expected now I wanted to add some extra padding to the left and right so after I added padding of ten to all sides I'm going to specify padding again but this time I'm going to specify eight just the left and the right like trailing and leading so let me specify an array and I'm gonna put leading in there comma trailing and the length of that is gonna be 30 so that's gonna be give me a bigger button and then I'm going to set the corner radius to 20 again so that gives me that look now we probably want to add our spacers now because we have all of our elements so I'm going to add a spacer in between here and between here and in between here and also probably at the top in the bottom space right there at the bottom got a spacer in between the button and there got a spacer in between the cards and the credit counter and then another spacer between the credits counter in the title and then I could put a spacer there as well so there in this app I actually used padding instead of a spacer up here but right now on the whim I'm deciding to use that it's just fun okay cool so now all we have left to do is when they hit spin we're gonna write the code here to change the images but there are a couple of steps we have to do before this because here we hard-coded the images right so we're not going to be able to change them unless we make them state properties as well so let's first start by declaring an array of the different asset names so I have private of our symbols equals we have Apple we have star and we have cherry and the second of all this is going to actually be a state property we're gonna have an array containing or representing the data representing which icon these these reels took so you know this could be from 0 to 2 right so 0 would be Apple one would be star and 2 would be cherry so this array this numbers array represents the state of what symbols these guys are so what we're going to do is when the user hits spin we're going to randomize a number from the between 0 to 2 representing one of these symbols and we're going to place it into you know these slots are representing these three cards here and for the images for the image elements here right instead of specifying Apple what we're going to specify is the symbol array right symbols and inside we're gonna specify since this is the first image this would represent alright let me just type this out first numbers okay so this is the first image right so numbers 0 is is the the value that represents that cart right this is going to be index 1 and this will be index this guy's going to be index to this guy's gonna be index 1 and this one's gonna be index 0 so essentially instead of doing that we are going to do that okay so hopefully this makes sense to you so for example right now it's still showing apples because you know the numbers are all zeroes but let's say we randomized it and we get one for this we get two for that and we get zero for that so if we resume it again now you're gonna see them different the reason for this is because this one is reading one so it's gonna grab that symbol and this one is two so that's going to be zero one and two so it's gonna grab that image and finally at that position we still have zero and zero at that index we get the Apple image so that's what we're going to do here so inside the button action we're gonna randomize a different number for each of these indexes in the numbers array so we're gonna do self-thought numbers 0 is equal to int dot random and where's my autocomplete there we go so we're gonna randomized between 0 to the number of symbols that we have minus 1 and that's going to give us 0 to 2 all right we're gonna do the same thing for number one and number two so even just doing this we can go ahead and run our app and take a look at these guys are randomizing because we should be able to see our UI update automatically remember that number says a state property right so when we're changing these indexes the value inside these indexes the UI is going to see that change and it's going to automatically update what image those image elements are displaying okay next up change the images we're going to check check winnings and let's declare another one up here another property here for the bet amount and we'll say five each time they spin we'll take away five credits and if they win if they get a match we're going to give them let's say ten times their bet so here we're going to check winnings and all we have to do here is just say if you know self thought numbers zero is the same thing as numbers one and self thought numbers you know if the second one is equal to the third one then all of them are essentially the same one so we can say self dot credits equals plus equals that amount times ten else self-thought credits - equal vet amount - oops I forgot the self keyword there as well all right so let's take a look and see if this works yeah so we can see it deducting here and when we can finally get a match this is why you shouldn't gamble oh there we go I don't even know I guess we could add a label to just say what the status is but this is where I'm going to leave things here because we have a working slots app in the next video we're gonna talk about some of the core guiding principles in Swift UI and then we're going to come back and improve this app so in this single video you built a working Swift UI app isn't that amazing however I did mention that there are improvements that we could make to this app structurally to enable us to build upon it and take it even further in future videos in the next lesson I'll tell you about two of the most important guiding principles when it comes to Swift UI regarding data flow and view composition after that we're gonna come back to the slots app and make those structural improvements that I talked about thanks for watching and I'll see you in the next lesson hello and welcome let's talk about two very important principles in swift UI data flow and view composition let's start with views so what is a view a view defines a piece of UI there are kind of like the basic building blocks and just like Lego you want to build a bigger view out of smaller single purpose views this makes it easier to understand and easier to maintain over time as well so let's use an example to illustrate let's say you have a view that represents a color picker and it looks something like this and because you know that it's a best practice to break down a view into reusable parts you decide to create a smaller view that represents the slider now you can reuse that slider view three times in your color picker view pretty easy to understand right it's all about reuse let's talk about dataflow now now if you came from working with UI kit you might have noticed that we don't have a view controller anymore to understand why there's no view controller in Swift UI let's take a look at what the view controller was used for with UI kit the view controller managed the data flow between your model and your view it was responsible for updating your UI whenever the data in your model changed for example let's say you have a contacts app and once the data model finishes loading the contacts the view controller takes the data and manipulates the UI to show the data conversely the view controller was also responsible for handling user interaction in the view and changing the data based on those interactions using the same example let's say that the user deletes a contact from the UI then the view controller would have to let the data model know to remove that contact this is the way we've been used to doing things but there's a lot of code that you have to write in order to make all of this happen so in Swift UI things are a lot easier for us the view controller is removed and instead of having to write all this code to manage the data flow instead we bind the data in our model directly to our UI we don't have to write any code to do this and this way whenever the data in the model changes the UI will notice and update itself accordingly this diagram from WWDC shows clearly how the data flow in Swift UI works now let's say the user makes a change from the UI for example delete the contact because your view is written in code you can have code in your view that handles that user interaction and goes to update the data in your model to remove that contact the UI will notice that the data has changed and will update itself automatically so this loop eliminates a lot of the coding that we had to do previously inside the view controller the next question is how does Swift UI achieve this sort of data flow that we see in this diagram without a view controller well Swift UI has several different ways for now I want to talk about state and binding and when you should use each of them you've already seen what a state property is in previous lessons you can bind the state property to a piece of UI and have the UI update itself automatically as the data in that state property changes but how does this work if we try to break up the view as a composition of smaller views after all that's one of the guiding principles we talked about in the first part of this lesson so let's use our color picker example from earlier let me quickly point out what data these views need in order to display the UI the color picker has the color square and in order for us to display that we need to know that different amounts of red blue and green however each of our three slider views also needs to know the amount of red blue and green respectively now let's take a look at this view in code form so that we can clearly see where to put the state properties and bindings to make the data power the UI since you've only learned about state properties let's use that for everything we said the color picker view needs to know the amounts of red green and blue so we'll have state properties there then each slider View also needs to know their own amount of red green and blue so we'll have a state property in the slider view this state property will be bound to the slider element and text label so if the user uses the slider it'll update the value in the state property which results in the text label being updated there's a problem with this picture though since each slider view is tracking its own color value independent we've essentially duplicated the data and we're now tracking the value of each color in two places furthermore how is the color picker going to know about the data changes in the slider views because it has a color square that it needs to update so this is where bindings really come in handy we can have a binding that reads and writes to and from a state property and then we can pass that binding into a subview for them to use let me demonstrate so here I've got the color picker view project and we're going to break it down into smaller views and I'm also going to show you how to use bindings as well so just to quickly run this for you so you get an idea of how it works we have three sliders you can adjust the levels of red green and blue and as you can see from here there's a V stack there's a rectangle representing the color square and then we have three sliders also take note that we have three state properties up here representing the amount of red green and blue and the rectangle his foreground color is is reading from those state properties red green and blue and so are the sliders the sliders are bound to red green and blue and that's why adjusting them affects the state property which affects the foreground color now if we were to follow that first principle we talked about in terms of view composition looking at these three sliders they look very similar they would be a perfect control to abstract into a smaller view right so that's exactly what we're going to do right here let's stop this and then we're going to create a new file and we're gonna choose UI swift UI view and I'm just gonna call this a slider view so it starts off with a text field sort of text element and we're gonna go back to content view and I'm just gonna take one of these sliders I'm gonna copy it and I am going to paste it in there now because this used to be inside a big view stack or V stack it's no longer inside Avista so we have to and declare a V stack there and we'll put the slider and the text element inside furthermore we no longer have this binding and this label needs to be dynamic as well if we're gonna reuse this slider element so up here I'm going to declare first of all a a text property actually a string property and I'm going to actually I'm not going to initialize it because I want the the color picker view the past in the text to use so instead I'm just gonna call it label I'm gonna make it a string and I'm gonna leave it uninitialized and then for the text here we are going to insert that label property now as for the binding for the value what we're going to do is use the at binding property wrapper and we are going to declare it as far let's call it value and the type is double now in here in the slider I can bind to I can pass in that binding value right and then in here instead of showing red we're gonna show value as a number now these two are going to get passed in when we create instances of the slider view in the color picker as you'll soon see but first let's fix one thing in here this is the preview we can't see anything on the right here because it's missing initialization parameters so let's go ahead and do that so that's what we have to pass it and we have to pass in a binding and we have to pass in a label which is just the string now you since we don't really have a binding to pass in right here what we can do is we can do binding dot constant and just pass that in as a constant value it's not a real binding per se but for the purpose of this preview it works brilliantly so for the label I'm just going to call label and then let's hit resume here let's see if we can preview something there we go so there is our label and it reaches all the way to the edges we're not going to add padding to this V stack here because inside the content view in this bigger V stack we already have padding as you can see here on the left and right so just to make it look prettier in the preview I'm going to add the padding to the preview so this doesn't affect the actual app it's just so that we can see an accurate representation of what that looks like and now we can go back to the picker view and instead of having these slider and text elements we can remove it and replace it with our new a specialized view so there's our slider view and we have the pass in a binding and a label so for the binding that's what we want to pass in a binding to that state property so we're gonna use the dollar sign read and the label is just gonna be read right and we're gonna copy that and replace this slider and instead this is going to be dollar sign green and this is going to be green as well and then as you can see it's actually changing it in the preview this is going to be blue and this is going to be blue as well so now let's run our project and just make sure everything is connected and it works so as you can see there's red there's green and there's blue not just like that you've seen a demonstration of us breaking down a more complex view into smaller reusable views as we've done here and you've also seen an example of using bindings you see the color picker view that we have here owns the state properties for red green and blue so it's the source of truth and we are passing in a binding to those state properties into our slider view so that the slider view can both read and write to the state properties up here as you can see a binding provides two-way communication the slider view can read the value of the state property in the color picker view and it can also manipulate the value of that state property through the binding but a key difference is that the color picker owns the data because the state property is declared in the color picker view we're no longer keeping two copies of the same data the color picker view is the source of truth when it comes to the values of red blue and green and you'll hear this term a lot in swift UI source of truth it refers to who owns the data because you want to avoid two views both having state properties representing the same data instead you should think about who should actually own the data aka the source of truth and have the other views use bindings instead in the next lesson we're going to apply these principles to our slots app all right I'll see you there hey code crew in the last Swift ey lesson you learned about composing complex views using smaller single purpose views and you also learned about data flow using state and binding properties well in this video we're gonna take a look at the slots app that we built and we're gonna see how we can apply these two principles to improve that app alright let's dive in so here we have the slots UI app that we built together a couple of lessons ago and again if you've missed that lesson you can definitely check out the playlist in the link in the description below to follow the series from the start alright so the first thing we're gonna take a look at is what makes sense to break out into its smaller single purpose view and what I like to look for is anything that I tend to have to repeat in the UI so if you've got the same sort of button in a couple of different places or maybe the same type of image element like we do here I mean rather than having this code repeated three times like we have right now we can abstract that card out into its own card view you know its own single purpose of view and then create three instances of that instead just like in the last lesson when we talked about the color sliders so here you can see the code for these three cards we've got these three images they're virtually the same code except for you know what icon gets displayed but we can always use the what we learn about dataflow right you state properties and bindings and pass that data in and the other thing that's good about abstracting this into its a single view is that you know if I wanted to change the look and feel of the cards you can see this code is repeated three times if I wanted to change the corner radius or the background color a little bit I'd have to change it three times but if I abstracted out into a single card view and then just use it three times then I only have to change at one place so it makes maintenance easier so let's go ahead and just do that first before we even talk about dataflow so right click here I'm going to add a new file and under iOS or under user interface we're gonna choose Swift UI view and I'm gonna call this the card view because that kind of makes sense I'm just gonna move this guy up here and by default you get that text label saying hello world but we don't need that we're gonna go into the content view again and I'm there really just gonna copy this guy and I'm gonna paste it into here at the body this piece of data we don't have inside this card view so I'm just gonna hard code an image name for now just so we can see something on the right hand side so that's great this lets me know that this is working right and this preview is simply creating an instance of the card view and that's what we see so we'll take that and we'll go back here and I'm going to first remove this one let's do a little test and let's declare a new card view element here you can see that changed I'm gonna do the same thing removing that middle card and same for the last one and that you know just like that we have created a smaller single purpose view in the car view and we've composed we've used it to compose this kind of like bigger more complex view now for this simple swift UI slots app that that is the thing that makes sense to abstract out into its view if we were to you know reuse these other elements in different places if it were a more complex app then there are probably more components that I could pull out and make into smaller views but as it stands now I think that's all that makes sense now we run into the next problem which is that these cart views have a hard-coded Apple icon in the cards so we need to somehow be able to change icons now the consideration for the data flow comes into play so who should be the source of truth for these icons here just to remind you about how they get displayed you know we have a we have an ax right here called symbols and there's an apple star and cherry these represent the possible icon choices or the image names and we have another array called numbers which indicates which icon that card slot should be so this first index of the numbers array represents this card the middle one represents that card and the last index represents that card so depending on what number this is it's gonna kind of result in a different icon here remember in the last lesson we talked about source of truth you know the state properties so we definitely do not want to keep a copy of the numbers here in the content view and keep a copy of you know what individual index this card is also in the card view because that would be duplicating the data right and so it makes sense for me that the content view should be the source of truth and that it should be passing the bindings to these numbers to the card views itself because number one the content view has the logic to check for matches right after they hit the spin button we have some code right here just to check if the numbers you know if this one matches this one and if this one matches this one if we made the card view instead kind of hold its own number right if we had a state here and we said you know we made it hold its own number it would make it harder for us to be able to match to see if this card matches the others so that's why at least my thinking is that right here the content view should be the source of truth of this data and instead we should pass the bindings into the card views so that's what I'm going to try to do here let's hop into our card view and take a look at what we can do so this is the hard-coded string that represents the image so I'm going to create a binding for it so that it can be passed into the card view when it gets created instead of having a hard-coded string there so I'm gonna say binding we're going to say let's just call it symbol it's gonna be of type string I'm not gonna set it to anything because I want it to be passed in and then here instead of hard-coding the string I'm just gonna put symbol and now this preview is broken because you can see here you can't just create a card view element and expect it to be displayed because it needs to know which symbol to display right and it is expecting a binding to be passed in so if you just get rid of those parentheses or brackets you can see that you're supposed to pass in a string type binding so unfortunately we don't have any real binding to pass in to this preview right here but what we can do is pass in a temporary binding value to just for the purpose of the preview so that it can display something so the way you do that is you go binding dot constant and then you can specify a value so it's got to be a string so let's let's do cherry so then it's still gonna allow you to you know pass this in as a parameter but it's not a real binding you know it's just a constant value so unfortunately it's not building right now let's just take a look at why here card view type is not convertible ah yeah so back in the content view all of these are broken now as well so why don't I just do the same thing just so we can just do one thing at a time so let me just show you that this this works now we can actually see something before we actually use real bindings yes okay so there is the parameter label right there okay so if we go back to the card view now and we try to update the preview you can see that we see cherry because that's what we put right here all right now let's go back to the content view and take a look at how we're gonna pass in the bindings for the symbols alright so up here my numbers this is already a state property I'm going to change this to a state property as well now I'm gonna go down and instead of passing in a binding constant for a cherry right here I can pass in a real binding from the state properties up there that we declared up there so we have symbols and then inside here I had I think I called a number right so this would be zero all right let's just see if that is okay before before I do anything Oh numbers okay so it would help if I could remember my property names all right so we're gonna do the same thing here as well numbers 1 and this would be symbols numbers - okay so let's resume build succeeded and you can see that this reflects the indexes that we have right here in numbers and if I build and run this that I forget anything let's take a look alright so you can see everything is working perfectly here and we've successfully abstracted the card view into its own single purpose smaller view and we've facilitated the data flow where the content view is the source of truth for the symbols and what indexes those cards should be and then passing that into the card view element as the binding alright now I want to solve another issue here which is that it's really hard to detect when there is a match like we just had if you can't you can't even see it unless you notice your credits going up but the same time they're going down so it's always changing and this was just really hard to tell when you get a match and so what I'd like to do is change the backgrounds to green when there is a match and this is going to give us another opportunity to practice using state properties and bindings so I'm gonna create a state property up here for the three background colors for the cards just like we have here that represents you know which icons they are and then we're going to pass that as a binding into the card view here and have the background change when there is a match all right so first let's declare a new state property here I'm gonna call it backgrounds so I'm gonna default them to all white and all three slots and then let's go into the card view and add a binding so instead of just using white by default we're going to have that value as a binding and this is gonna be of type color and again I'm not going to assign anything to it here so that we are going to be forced to pass it in when we create the card view element and don't forget instead of hard-coding white we're gonna use the binding alright so here this preview is broken because now we have to pass in an extra binding so let's go ahead and just hit fix so it adds that label for us and then we're gonna do a binding constant well this is gonna be a color so let's just say green we'll save it and I'm pretty sure this preview is actually broken yeah because the project is broken right now don't forget we just added another binding and inside content view we create these three cards these are not valid instantiations of card view anymore so it expects say another another binding to be passed in all right so let's add that parameter here and we're gonna pass in the background color so backgrounds zero right this is a binding for the state property that we have up here so that's where that's coming from and we're gonna do the same thing with the second card view let's have that parameter and then backgrounds one this time backgrounds - okay so now everything's set up if we run the project now it's gonna be fine but however the backgrounds aren't going to change because we actually don't have any code to update the backgrounds state property so we have to update that when there is a match and we have to don't forget we have to set it back to white when the user spins again so right here they won so we're gonna update the state property update backgrounds to green so we're gonna say self-thought backgrounds equals color green we're going to do this for all three and I'm going to show you another way of writing these three statements using a map function and just in a second but let me just do it this way first that might be something you do know or something you don't know but it'll be helpful set backgrounds back to white here because this is where the user hits the spin button before we actually spin anything all right so we have when the user taps on the button we set it to white and then if there is a match we update it to green so let's run this project and watch our code take effect so it's white did you see that there we go so that's pretty cool so now let's talk about that map function I mentioned so the map function is something that you can do with a race when you want to do something with every single element of the array and it's a more concise way of writing it rather than repeating yourself three times like this and imagine if we had even more backgrounds like nine backgrounds or something like that then this would be nine lines of code so here is just another way to write this in case you don't know about the map function and I don't think I've really ever taught it in any of my other videos just yet so here's how it goes so it is a function that you can use with an array so you go dot map right and you pass in a closure and this is the code that you want to run on every single element of your right so you can see that there is this is the element this parameter here represents the element that is currently in that array slot or you know this is the element that you're transforming because we don't want to transform the color white like we're not gonna do anything with that color instead we want to replace it right we want to assign something new into that slot so we actually don't need this parameter so we're just going to replace this with an underscore and as for the code we simply write color dot white and that is essentially going to replace whatever was there and look the result of the call to map is unused because this function basically returns a new copy of your rate does it modify your old one so what we're going to do is we're going to assign it back to self dot backgrounds just create a little more space here there we go and so this although it's still three lines is a little more concise than writing this a little more elegant but I do want you to keep in mind that this is perfectly fine this really comes in handy when you have many elements in an array so I'm just gonna show you what it would look like we did it like this right you could do this with the color green down here and then if you're really observant you can also notice that we are running the same operation on every single element in the numbers array as well so we can use a map here so self dot numbers equals self dot numbers dot map alright let's open up that closure again it's gonna give me the integer currently which is the element in that in that slot we don't need it so we're gonna put underscore because we are assigning and we're just gonna run this code right here and it's basically basically going to run this code for every element in the array and assign it to that slot so get rid of this and that's that's an even bigger savings right like that made the code a lot more concise but the thing is for a lot of the beginners who are watching this I don't want to start doing this too much because it's kind of hard to know what's going on if you are just starting out and my primary focus is making sure that you understand the code and you can follow along in terms of the logic and understanding and so you know if if it's a lot of extra work like if there were nine elements and I'm doing the same thing to every element that maybe I'll I'll just mention and use the map again but for this I'm simply gonna do it the simplified not so not so concise way just so anybody who is reading this no matter kind of what the level even if you're just starting out can easily understand what we're doing however now you know that this map function exists you can add it as a tool to your arsenal for your Swift development oh yeah our slots app is progressing really nicely and if you're up for it I actually have a challenge for you can you add two more rows one to the top and one to the bottom for a total of nine cards and make it so that matches can occur horizontally on all three rows and also diagonally and for extra bonus points can you add a second spin button so that the user can either tap one of them that only checks the middle row for matches in the second button which costs five times as more credits or whatever amount you want but that second button checks for just on all three rows plus the diagonals so it's gonna cost more it's higher risk but a higher reward oh and I forgot one quick tip for the challenge that is actually quite crucial so in any of these containers like Zed stack or Z stack V stack or H stack any of these containers they can only contain a maximum of ten elements inside but don't worry you can nest it so let me just give you a quick example inside of this V stack we have a spacer that's one that's two that's three that's four that's five that's six that's seven that's eight and that's nine so inside this V stack we have nine elements already so you can put one more element and that would be 10 and that would be completely okay but if you try and put an eleventh element you're gonna see an error and the thing is the error message isn't very helpful because it's just gonna point to something else at least in this example it's not actually telling you what the real problem is and that is that our V stack has 11 elements so how do you how do you combat this well you can let's say this is one solution you can nest these two elements inside of their own V stack and although in this example it kind of changes the way things look but that's just to get your thinking going so just keep in mind that there is a 10 element limit per layout container and that if you encounter a Swift UI error and your preview won't work and you can't build your project and the error message doesn't really make sense just remember that you can double check that and as a solution you can nest these things together share a screenshot of your completed challenge with me on social media and make sure to tag me so I can see it and if you also want to earn a special forum badge for your achievement make sure you post your screenshot in my code crew for under this topic I'll link to that forum thread in the description below and if you need help with this challenge the code crew forum is going to be the place to go to get help from myself the team and other developers just like yourself alright thanks for watching and I'll see you in the next lesson all right so this is the solution for the challenge and just to recap I asked you guys if you could do nine cards with two buttons the first button spinning only the middle row and the other button spins all of the cards and matches all three rows plus diagonals so that's what we're going to do today so the first thing we're going to do is actually to increase the number of cards that we have and this is actually relatively simple so we're gonna go into I'm gonna go down to where the card view is I gave you guys a tip last time where you know you're not going to be able to just create three rows like this because you're gonna get an error which is not very helpful it tells you that there's an error with this corner radius modifier but that really isn't the case the problem is that in the stack view that we have that contains everything it's got more than ten elements and right now stack views can only have a max of ten in fact any sort of container layout element can only have up to ten and so what we're gonna do is in case these three H stacks you know these are our nine cards here inside its own V stack so I'm gonna cut all of that I'm gonna declare a new or write a new V stack there and just paste all three rows and we should see all the cards alright so that's really cool the next thing to do then since we have so many cards is to expand expand our numbers and backgrounds because these two arrays represents the different slots or indexes for these cards and now we have more than three so we need you know we need nine so one easy way to to do it is like you could you could just create more elements in your array literal like that but there actually is a method for creating a race if you want to fill it all with the same value and I'm gonna show you that in a second but let me just show you this way right now so there are six and there's nine so you could do it like that and you can have each of these indexes represent a different card so we're gonna erase this literal here and we're gonna declare a new array object and we're gonna use this initializer here it creates a new collection containing the specified number of single repeated value so the value is going to be we're just going to put 0 and the count is going to be nine for that and then for this one for backgrounds we're going to do the same thing alright and we're gonna use this repeating one and it's gonna be color white and again nine then we can erase this literal here all right so that's what we have and the next step is to update all of these card views we're going to pass the appropriate bindings in so this one is going to be at index 0 1 2 3 4 5 6 7 8 right I almost counted 9 you guys probably caught that and he so there's 3 this one's for since 5 this one 6 7 and 8 and if we just update this where we should see all of them as apples right ok so now the next step is to take a look at our spin button here so what it does right here is it sets all the backgrounds to white and then it randomizes a number for the 3 cards and then it it checks for the winnings like if 0 matches 1 in 1 matches 2 then you know that all three match and then it updates the credits and then it that's the background to green so in the last lesson when I finish the slots app I taught you guys about the map method for a race and we're actually going to use it now because setting nine different backgrounds and like you know randomizing nine different cards and setting nine different backgrounds to green is just is too much so we're gonna make use of that map function here but before that we're gonna abstract this code out into its own method the reason being right now we've written this code directly in the closure for the action for this button but we remember we're gonna have a second button that is gonna have very similar code because that button is gonna set all the backgrounds white as well but it's gonna randomize all nine cards and it's gonna set the backgrounds to the matches to green and it's going to calculate the winnings as well so rather than repeating this code right for nine different cards we're gonna kind of abstract it out and write it more elegantly so what I'm gonna do is I'm gonna create a method right here right before the closing bracket of this body property we're going to call it process results alright and we're gonna need to know if we're processing the results for one spin or like the maximum number of spins which is like all three so I'm gonna have a boolean to say is max and this is going to be a bull all right let's default it to false so by default it's gonna be a single spin and I'm just going to take all of this code in fact all of the code for this button closure for this action and we're gonna put it into here and the first thing we're gonna do is set all of the backgrounds for all of the cards to white so instead of going you know zero to eight we're gonna do self thought backgrounds equals self thought backgrounds dot map and I'm going to open up that closure and we don't need this parameter part and we're just gonna return color dot white and just like that we've set all the backgrounds to white maybe I can just get rid of this pain right there and that's gonna be a little easier to see alright now we're going to randomize the images but this depends on whether we are doing a maxis pin or a single spin right so we're gonna have to we're gonna have to do an if statement if is max then spin all the cards else spin the middle row alright so spinning the middle row we're gonna have to do it in three statements and the middle row is 0 1 2 3 4 and 5 so 3 4 & 5 that's the middle row right so we're gonna do 3 4 & 5 but for spending all the cards again we can use the map function here so self dot numbers equals self dot numbers dot map and we're gonna open up that closure remove this part because we don't need it and we're gonna say we're gonna return int on random actually I'm just gonna copy this because it's the same thing for every single element all right so that's spinning all the cards or randomizing a number for every single index and this is just randomizing four three four and five alright and here's checking for the winnings now this is also more complicated now because if we're spinning a single spin then we only checked the middle row but if we're spinning max then we got to check one two three and in the X right four five that's like five different things so rather than have it here I'm gonna write a different a different method down here called process process win and again this is going to accept a parameter is max we're just gonna default it to false okay so I'm gonna I'm gonna take this chunk of code right here and I'm gonna cut this and I'm gonna paste it in here right and then simply I'm going to call process win from here and then pass in is max this is from up here right so this method is for processing the results but in actuality it's like just to spinning all of the indexes or randomizing all the indexes this is for processing the win which is to we're going to check basically all of the matches so let's declare so with a single row that was easy right if it matches then you win if it doesn't match this then you lose but for a max spin because there are so many different matches that can happen you can match you know you can match one you can match two you can match all five so we need to keep track of how many matches you've made and so I'm going to create a variable here I'm going to call it matches equals zero we'll initialize it to zero and then what kind of keep count so we're going to first check the case where it is max equals false so let's say this is a single spin right I put this inequality here this means that if it's not is max then we are processing for a single spin so we've already got we've already got this here right except we're not checking 0 1 & 2 were checking 3 4 & 5 so if 3 equals 4 and 4 also equals 5 then that means there's a single match and we update the backgrounds 3 4 & 5 to green right and 1 I would I would instead of doing this we're gonna update the number of credits at the very end based on how many matches there were so in here instead of updating this the credits balance here we're just going to say matches plus equals 1 ok so that is if the cases if the case is not is max if that's a single spin else processing for max the spin I'm going to remove this code so we don't kind of confuse ourselves this was the code from before and then you know after we process for max spin this is going to require a couple of different if statements right so I'm gonna I'm gonna shorten it after I write it this way just so you guys are aware but right now we're gonna check row by row so we're gonna say top row and this would be 0 does 0 equal to 1 does 1 equals to 2 if so matches plus 1 and turn turn these cards green okay now we check middle row so middle rope is when you know we've already got the code from up here so I literally just pasted it here if the middle row matches then matches plus equal one this is bottom row bottom row is 7 6 7 8 so 6 equals the 7 and 7 equals to 8 then we're going to update 6 7 & 8 to green we've got two more to do so diagonal diagonal top left to bottom right so that this would be 0 with 4 right 0 1 2 3 4 with 4 and this would be 8 so 0 4 & 8 okay and then we've also got a diagonal top right to bottom left and this would be 0 1 2 2 4 & 6 okay and finally that's good finally check matches and distribute credits so if matches is greater than 0 then that means that there is there is a win right if else if that means if it comes to me here that means matches is 0 or less than 0 which it can't be less than 0 so it's just 0 else if not is max so this is at least 1 win this is 0 wins single spin and then lastly its 0 wins max spin so if it's you know if it's zero wins single spin then we're going to do self dot credits is minus equals that amount so we had a bettin amount up here which represents how many credits gets spent for a single spin and I'm gonna do it so that for the max spin I'm gonna do it five times the amount of a single spin so it's gonna deduct 25 credits instead alright but if you win then you're gonna get you're gonna get more credits back based on the number of matches you have so matches thumbs bet amount but you usually have to win more than you bet more than the amount that you just bet so I'm gonna say you you're gonna get two times back if you if you make a match you're gonna get two times back and you know multiplied by the number of matches you made so that's that's gonna be the math there and now let's add before we optimize this and kind of long chunk of code here I want to add a second button here just so we can start testing it and just making sure that this code is right before we go and shorten it so let's go back up here for our single spin button remember I had removed the action but now I can call process results right and is maxed by default is equal to false so I'm just gonna you know say that I process a single spin right and furthermore I actually want to put some text down here to say how many credits it costs so I'm gonna say V stack and I'm gonna put a text element here I'm gonna say five credits and I'm gonna take this button I'm gonna put it into this V stack like that and so we should see a little label down there that says five credits that's a resume all right so I spelled credits wrong okay I'm gonna optimize it a little bit so I'm gonna add some padding to the top let's say 10 and I'm also going to change the font to a like a caption style so it's a little smaller that's really small let's try footnote that's a little less slightly better if that's fine and instead of five I'm actually gonna sub in the bet amount in case we change that variable at the top so that's still going to be five all right now we are going to put this in an H stack because we have a second button remember so an H stack we're gonna take this button here we're gonna pop it in there and we're gonna add a second button so I'm gonna I just pasted it twice so now we have a second one this one's going to be called max spin the mountain of credits is going to be but amount times five so that's 25 and instead of just processing results we're gonna pass in true to indicate that this is a max spin and I'm going to add some spacing in between those two buttons so this H stack has an initializer this one so alignment we we don't need to specify that the default alignment is fine it's spacing right about 20 and this content closure is like I mean we already have this right there like this all this stuff is that parameter that content parameter okay so let's save this let's run this and see see how this actually works all right so single spin Oh match right away that's a win all right max spin cool wait that was a weird I think I saw a weird green pattern we might you have this oh wait this is a match yeah okay so row row diagonal well I still end up making money or losing money these are credits these aren't this is not money we are not gambling here I think we're going down here she is dying a slow death here at this point I'm borrowing money to gamble I mean the loan sharks all right this is cool so it's working let's optimize this code here because if you take a look at all of these parts that we have here the code is exactly the same but the only difference is that the indexes are different right see this code is checking these three indexes zero one and two and then setting it to green if it's a match that this section is checking three four and five so we can create a different a different method here and we're gonna call this is match and you're gonna have to pass in the three indexes so we're gonna have index one as an int index two as an int index three as an int and it's gonna return a bool so it's going to return false by you know if it reaches there but first it's gonna well it's basically going to check this if self-thought numbers index one is equal to self dot numbers index two and soft thought the numbers index 2 is equal to self tough numbers next three then this is considered a match and we return true and what we can also do is just also set the backgrounds to green as well but instead of hard-coding those indexes we would have index 2 and X 3 and this is basically a repeat of this code I don't know why I typed it out I see it see I typed something wrong oh there should be a space right there all right so now we can call this is match method instead of all of this code here so for example for this one we're gonna call you know we can do if is match and pass in 3 4 & 5 and if this is true then we can do matches + equals 1 right because our method didn't it doesn't increase the matches number I mean we keep track of this and here in the process win and then we can delete this whole chunk of code and if you want to short it if you want to shorten even more you can you know you can put it in one line like that so then this becomes you just change these numbers 0 1 & 2 you get rid of that middle row becomes 3 4 & 5 this becomes 6 7 & 8 this becomes 0 4 & 8 I accidentally keep pressing command B that's 2 4 & 6 4 & 6 so that actually saves a lot of code and you know it's gonna make updating this a lot easier maintaining it I mean and it also looks a lot better so let's just run it again to make sure nothing's broken you know what would be cool is if we did a jackpot type thing like if you get I don't know you can you can do you know those slot machines at least you know different configurations kind of give you like different amounts right now we have a standard amount just for three matches but if you had a couple more symbols in here you could do some maybe if you get like all cherries or something you just get an explosion of credits but anyways that does it for this one that's the challenge that I wanted to do I'll leave the jackpot thing to you if you want to implement that if you do end up doing that definitely shoot me a screenshot on Twitter Instagram tag me and um I'll show it off okay thanks a lot thanks for watching I'll see you in the next lesson
Info
Channel: CodeWithChris
Views: 167,539
Rating: undefined out of 5
Keywords: How to Make an App, How to Create an App, How Build a Mobile App, Xcode, Swift, iOS, Coding, Programming, iOS Development
Id: VlhcNR7Qrno
Channel Id: undefined
Length: 161min 37sec (9697 seconds)
Published: Tue Mar 03 2020
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.