Build Calculator in SwiftUI for Beginners (Xcode 12, 2021, iOS, SwiftUI 2.0) - Beginners

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
[Music] what's going on everyone welcome back to another swift video in today's video we're going to be learning how to build a calculator with swift ui from scratch so here's the app we're going to be putting together it looks like a calculator as expected and not only are we going to build a ui but we're also going to make it functional so here we're going to say 555 let's go ahead and add let's say i don't know 15 to it go ahead and sum that up with an equal and boom there is our results and of course we have the other operations supported as well so we'll say 75 divided by 5 and there is our number so we're going to be putting together this whole thing from scratch it's a pretty good primer for anyone getting ready to dip their toes into swift ui so let's get started by destroying that like button down below for the youtube algorithm get x code ready get excited let's jump right into the project all right we're going to go ahead and get started by opening up xcode and we're going to create a brand new project right here we're going to stick with the app template under ios go ahead and pick that give your project a name we're going to go ahead and call it calculator make sure your language is set to swift and both your life cycle and interface here are set to swift ui go ahead and continue save the project wherever you'd like we'll toss it onto our desktop and first things first we're going to expand our xcode window i'm going to hit resume on the right hand side to load up our preview and once that decides to load up we're going to jump right into it so let me expand the code side here so we have a little more room to work and let me also hit this drop down to pick a little bit of a more modern device let's go with the 12 pro max and let's start building out our calculator so this is a bit of an impulse video so let's see uh let's see if we break anything along the way but first things first what we want to do is start off by adding a z-stack and a z-stack we're going to add a bottom layer of a black color and that'll give us a black color right off the bat since the background of our calculator will be black you'll see that we have these uh the safe area being accounted for at the top and bottom so we're going to say uh edges let's see edges ignoring safe area and we want to ignore all of them so the black background takes up the whole thing next up we're going to want a vertical stack and this vertical stack is going to basically hold two things first the text display of the calculator and then the next thing it's going to hold is our buttons so let's think about how we want to actually create our buttons and before we do that let me just go ahead and add a text here and let's just go ahead and say it's a hard coded zero value to start off i'm going to go ahead and make it bold we are also going to go ahead and give it a nice larger font size maybe 50 let's go with 52 perhaps and we see we get our text here on the right but we also want it to be aligned to the right hand side and we also want it to be let me go ahead and fix that system font of size 52 we also want it to be a white color so i'm going to say foreground color is white and to get this to be on the right hand side in terms of alignment we're going to wrap this whole thing into a horizontal stack i'm gonna drop the text in right there and we're just gonna put a spacer uh in here right before it and the spacer will be basically pushing the text all the way to the right hand side you'll see on the right that it's basically touching up against the edge of the screen which is kind of ugly so we're going to add a padding modifier to our horizontal stack and that'll give us a little bit of padding like so maybe we want this to be even a little bigger all right looking good so there is our text display pretty simple let's go ahead and talk about the actual buttons which is the other of course pretty important component in a calculator so what we're going to do is we're going to create an enum of calc button and this enum more or less is going to have a list of all the different button types now you might be wondering why we want this and you'll realize in just a moment so bear with me here so let's go ahead and create a case for each of the uh each of the types of buttons we want so i'm going to say we're going to want one two three four five six seven eight nine we'll need a zero a plus minus multiply divide a decimal a clear and a percent and maybe a negative so those are all the buttons we're going to need let's go ahead and quickly tweak these so we'll say two three four five six whoops that's not how you spell six six seven eight i know this is pretty tedious but just bear with me here nine whoops there we go nine we got zero what else did i say we want to add subtract we also want to divide and multiply multiply and we are going to want an equal of course as well and let's think about what else we need we want a clear button we want a decimal that makes sense and what else did i say we want a percent and i think we want one more which is going to be a negative positive positives i'm just going to call it negative just like that so there are all the different buttons that we want we're going to also say this enum has a raw value type of string and now in our view itself we want to have a two-dimensional array which is going to represent the grid of buttons in our calculator so what do i mean by that so here i am going to say lead buttons and this button is going to be a two-dimensional array of calc button that is not what we want there we go calc button and i'm just going to go ahead and uh create each of these inner arrays with the buttons that we want so let's let's just start with the numbers because they're nice and easy so this one's going to be 7 8 and 9 and before i go ahead and add the other ones let's go ahead and start creating the buttons here based on this array so you guys can get an idea of what we're doing so right below this horizontal stack what we're going to do is we are going to do a four each uh over buttons and let's see we're gonna have an id and this id will be self and this is going to be row in because keep in mind that buttons is a two dimensional array and then in each of these we're going to do another for each over the row once again id is going to be backslash dot self and this is going to be button in or you might want to call it item we'll call it item in and each of these guys is going to be a button with an action and the actual uh ui for the button itself so the ui is going to be a text we're going to say item dot raw value and let me go ahead and give it a little bit of styling so the first thing we're going to want is a frame and let's go ahead and hard code these so let's say the height is 70. we're going to adjust how we uh figure out the size here in just a moment the width is also 70. 70 not let's see height and width i believe that's the order of parameters i might be lying to you let's try width and height all right so there's that we're also going to go ahead and give this a background color and i'm going to go ahead and stick with color.orange we're going to say this has a foreground color of white and let's also go ahead and give this a corner radius of 35 to get a circle now it looks like our preview freaked out here so let's go ahead and hit resume to get it updating and we should see three buttons just like that so we see that they're vertical whereas seven eight and nine should be next to each other and clearly the text on them is not what we want so bear with me so in each of these rows what we want to do before we have this four each is wrap this thing inside of a horizontal stack because we want these three buttons to be next to each other so in theory this will be seven eight and nine below this will be um four five and six and then one two and three but we also want let's get rid of my antivirus pop-up we also want the text on this to be correct so how do we do that so right now we're using string here in our enum which is basically using the case as the raw value what we can do is we can go ahead and assign this each of these to a particular string itself so let's go ahead and do that really quickly i'm actually just going to copy and paste it for all of these and then we'll just tweak it at the end all right these are all one let's keep on going whoops that's not what we want to do and like i said this is a little tedious but it's fairly straightforward so go ahead and just just change the string for each of these it's giving me errors because you can't have the same string for each of each of these cases so just go ahead and add all of your strings here appropriately with the given enum a value so we'll say eight nine this one is zero this one will be a plus this one will be a dash this will be i'll use a backslash for divide this will be an x for multiply equal i guess for this one we'll say ac for all clear uh decimal is a dot percent is this guy and negative i think this is like a minus slash plus and now if you take a look on the right hand side and we hit uh resume up here because our canvas doesn't like to keep up with our coding we now see seven eight and nine so first thing that i notice here is the text size is a tad bit small so let's go ahead and just bump this up so i'm going to say font size or just font rather is going to be system font with the size of let's try 32 let's see what that looks like that looks pretty good and now let's go ahead and extend our two-dimensional array here to have all of the other rows so i'm just going to add a comma here and copy and paste this a few times so let's see we want this one to be one two and three this will be four five and six now we want a fourth row as well keep in mind this one is going to be i guess clear uh percentage or clear negative and then percentage and let's go ahead and hit resume over here we should have many more buttons once our preview updates all right we've got a bunch of buttons now there's a couple issues observed right off the bat first things first these stacks and buttons are super close to each other and the buttons are small and we also need another fourth column of the actual operators so let's go ahead and add those so this one actually want one more row too now that i think about it so let's go ahead and add one more row in the last row we're going to have the zero the decimal and the equal and in the ones above it what we're going to go ahead and do is add the operators so the first one is going to be add next one is going to be subtract this one is going to be i guess multiply and hopefully i didn't miss any this one is going to be divide there are all of our buttons go ahead and hit resume you should see them all rendered just like that this last row is supposed to have three we'll take a look at adjusting the positions momentarily but let's go ahead and fix the the sizing and as well as the color of each of these because we want different colors for things so let's take let's take a look at the sizing first since it's pretty simple so we want to actually calculate the width of our buttons based on the size of the screen so what i'm going to go ahead and do is right in the view we're going to create a function and this is going to be called uh button width and we're going to say go ahead and pass in the item which is going to be the calc button to return the width for we're just going to return a cg float and before we actually use this item let's just hard code this what we're going to say is take the entirety of the screen and it's bounds dot width and from this we are going to subtract a little bit of buffer for each of the columns so we're going to say minus 5 times 12 we're going to have a buffer of 12 that i'll add in just a moment divided by 4. so bear with me while i explain that calculation for this horizontal stack we're going to add a spacing of 12 between each of these buttons that'll uh push everything horizontally apart we'll also need to add a bit of spacing between the height of each of these so let's see we can probably add spacing to this vertical stack the other thing you can just do is actually add a padding modifier to uh your horizontal stack so i'll say padding modifier for bottom is three and that should vertically space your rows a little bit apart from each other go ahead and hit resume and let's see what that looks like everything should move up there we go looks looking better and let's take a look at using this function now for button width so here we had hardcoded 70 for the button with which is not what we want to do so we are going to say this is self dot button with whoops self dot button with and we're just going to pass an item which is the item we're getting in our loop and you'll see that the width starts to look appropriate but now everything is smushed vertically so what i'm going to go ahead and do is we're going to actually take this whole thing and i'm going to create another function in here which is going to return our button height we can say funk button height and this is going to be the same for every button so we're just not going to have a parameter and we'll simply just copy and paste that in there and the height is going to now be self dot button height just like that and things will start to look appropriate once you go ahead and hit resume on the right hand side hopefully all right looking much better so the other thing i notice here is uh it's not a perfect circle anymore so what we want to go ahead and do is uh for the corner radius we want to take the button with function drop it in there just divide it by two that's how you're going to go ahead and get that nice circle shape so if you go ahead and drop that there and we just click out of it everything should be a nice circle now so looking better we also have um way too much space at the bottom here so we want to push everything down so the way we can do that it's pretty trivial you can go ahead and add an alignment on your vertical stack or you can use the easier way which is just had a spacer to the top there and that'll push everything right to the bottom of your vertical stack so this is starting to look good let's take a look at how we're gonna get our colors to be appropriate because we want the numbers to be dark the operators to be this orange and these guys appear to be i believe like a light gray so all i'm going to really do is we're going to add a computed property into this enum and i'm going to go ahead and call this button color and it's going to give us a color back and all we're going to do is switch on south and if we are going to be you know any of the operands we're going to go ahead and return orange if we're the all clear percent or negative we'll go ahead and return to light gray otherwise we're going to go ahead and return the dark gray so i'm going to say if the case is add subtract what else multiply or i guess divide or even equals we are going to return dot orange if we happen to be the clear the negative or the percent we're going to go ahead and return a light gray and the way we're going to do it is just wrap color and say light gray and if there's any other case which should be the numbers what we're going to go ahead and do is return a dark gray so here we're going to go ahead and say return a color and we're going to create a custom color with rgb values so we'll say this is rgb and we're going to say 55 over 255.00 this is basically just a dark gray color that i've looked at beforehand let's see what this error is yelling at me about it should go away all right so now that we have this computed property here instead of hard coding each of these buttons to be an orange let me actually go ahead and close this left panel so we have more code room instead of hard coding each of these to have a background color of color.orange we can say item dot button color and i believe that's what we called it let me go and double check sometimes autocomplete with swift ui really doesn't work so let's see button color and here we have also said item.buttoncolor which should be our item let's go ahead and hit resume the right hand side and all of our colors should update boom look at that all of our colors updated and we're starting to look a lot more like a calculator so the next thing we want to go ahead and do is if you actually hit the little play button here you'll notice when you tap on each of these buttons you don't really get the nicest looking um uh event basically nothing's happening uh so what we want to go ahead and do is link this up to an action that's gonna actually change the text up here so we're gonna go ahead and create a function and this is going to be did tap and it's going to take in once more a button and this will be a calc button and we're going to go ahead and do something with this but we also don't want to hard code our display text up here we have it as 0 we're going to say this is a value and value is going to be a property which is going to be wrapped as a state up here which will be 0 by default now if you're not familiar with state property wrappers it basically allows you to control the various states of your view as things automatically change and update through that property the other thing i'm going to do is bump up this font size because i feel like it still looks a little small so go ahead and hit resume you can hit uh pause for this live preview over here and this guy should get a little bigger the zero let's also go ahead and fix the size of this zero button because this is centered and it really shouldn't look like that so the what we're going to do for that is pretty simple actually so when we calculate the button width we pass in the calculator button so what i'm going to go ahead and do here is we're going to say if the item is a 0 we want to calculate a different size so bear with me while i do some quick math here so the first thing we're going to do is copy and paste this and we're going to need to tweak these numbers so the uh first we need to subtract the amount of padding between the columns so there's one two three and four so instead of 5 times 12 we're going to subtract 4 times 12. we want to go ahead and still divide this by the appropriate number of columns and what i'll go ahead and do now is i believe we want to go ahead and multiply this by two so the zero takes uh two of the spaces for the columns so go ahead and do that and what you'll see is that the zero will get wider and both of these guys the decimal and the equal sign will start and align up with the columns here so that is basically how our ui is going to look i don't know if i'm being picky about this but i still feel like the system size here for the zero is too small so we're gonna make it a hundred all right that's that's probably big enough let's actually go ahead and get these buttons hooked up so what we want to do is first and foremost in this button whenever somebody taps on it the action we're going to call it is self dot did tap we called it and we're just going to pass an item pretty simple now in this function we want to do two things we want to discern basically did the user tap on a number or did they tap on an operator or did they type on clear so i'm not going to worry too much about the percent and the negatives and i think i'll omit the decimal as well but you'll get the general idea so what we'll do here is we are going to switch on the button that was tapped if they tapped on any of the operators we're gonna need to go ahead and store you know which operation is being uh done so let's go ahead and grab all of those just put a break there for now uh if the user tapped on a number but instead of doing number i guess what we could do is if if they tapped on clear we want to do something or if they tapped on one of the ones that we're not supporting at the moment which is decimal negative or percent we're not going to do anything otherwise just leaves us with a number what we're going to do is we are going to get that number by saying number is button dot raw value keep in mind this is a string and what we're going to go ahead and do is we're going to say if self self.value is 0 we're going to go ahead and say the value becomes number otherwise what we're going to go ahead and do is we're going to add the number to the end of the current value we're going to say self dot value equals and i'm going to interpolate the string here so we're going to say self.value is the current value and then at the end of that string we're going to tack on the new number so it's a little confusing so bear with me here in all clear this one's pretty simple we're just going to say self dot value once again it goes back to zero and we'll do these operators in just a quick moment here so go ahead and hit this play button and if you start tapping on these if i hit eight you'll notice it turns into an eight i can say eight seven nine clear so there is our calculator working pretty easily so keep in mind um you're gonna need to adjust the font size as you get into a larger number so that doesn't happen because that's not really appropriate but you guys get the general gist so let's actually go ahead and talk about these actual operators to add subtract multiply and divide which is actually the functionality so what i'm going to go ahead and do is we are going to create another enum up here and this is going to be called operation and what we'll go ahead and do is put four cases in here so this is add subtract multiply divide let's see divide i really can't spell today divide and equal and we're gonna have an initializer um and i guess we don't even need an initializer in here we can go ahead and do is uh we can put a property on our actual view and this guy can be called i guess current operation and this is going to be uh operation optional and maybe um what we could also have instead of making it optional so we don't want to unwrap it we can actually add another case in here and call this none and we can say by default that this operation is none and what we want to go ahead and do is you probably know already once we tap on a button we just want to store um you know which thing is uh which operation are we doing so we're going to say if a button is add we can go ahead and say current operation becomes add so on and so forth so let's go ahead and do that let's see that is add so let me go ahead and say self.current operation and make sure it's not going to yell at me let's see it's yelling at me because cannot assign to property self is immutable i think we should make it a var that'll be a great idea all right let's see var so we also want this to be a state i guess i'm not sure why it's immutable it shouldn't be immutable let's see this is none it is definitely a var let's see what's going on here so self dot current operation is should be able to make it an ad it's in a view so perhaps we need to make it a state let's go ahead and make that guy's state up there and we should be able to assign to it just like that and let's go ahead and just do a bunch of else ifs here this probably isn't the cleanest way to do it but we're just going to stick with it for the sake of time this will be subtract multiply multiply divide divide and otherwise we want one more which is going to be equal equal and equal so let's think about what we want to do so in each of these cases as long as it's not the equal we want to go ahead and actually reset the input value to be zero so the user can add the next number so not only do we want to set the operation but we want to capture the previous number so what i'm going to go ahead and do is we are going to add another state on here and this is going to be var running number and by default it'll be zero pretty simple and what we'll go ahead and do is if each of any of these operations occur what we want to do in each of these blocks instead accept equal is say self dot running number and we want to go ahead and increment this by basically whatever the integer value of the current value is and keep in mind value on self is a string and this guy is going to return optional so we're going to coalesce it to zero so we're gonna basically add uh to this this running number whatever the value is for the add operation and this is going to be different each time so if the user types in four and then they click on add well let's actually simplify this a little bit to start let's actually just assign this to be our running number and i'm going to do this in all of these before i get ahead of myself and if the user hits equal what we're going to go ahead and do is a little different so what we're going to first do is we're going to say get current which is self.runningnumber right makes sense and then what we're gonna do is we are going to switch on self.currentoperation and we actually don't want to even do that we're going to switch on that and we're going to say if the operation is add go ahead and add the values and that other current value is going to be let's uh let's call this running value and this one will be current value and this one is going to once again be self integer from the value string just like that and let's see let's make sure i do this correctly what we want to go ahead and do is say self dot value is going to equal the current uh the current let's see current value plus the running value so we're going to say this is running value this is current value so we're going to go ahead and add these together and that'll update the value string thus updating our ui so bear with me here this has gotten a little messy i will definitely go ahead and explain it all momentarily let me go ahead and get rid of this backslash let's go ahead and just add the other cases here for add subtract let's see multiply and divide and i'm actually going to remove equal from this operation since whenever equal occurs we don't really want to hold on to the equal we just want to go ahead and you know perform the operation and let's go ahead and change these so for subtract we want to say this is the running value subtracting current whoops subtracting current for this one of course we want to go ahead and multiply and the next one will want to divide so let's multiply and that's divide so let's go ahead and hit command b to make sure it's compiling first and foremost then go ahead and let's see looks like we have an error here let's see what the problem is so this is yelling at me that it needs to be exhaustive because we also need to take care of the case of none in which case nothing happens go ahead and hit command b one more time and that should hopefully fix all of our errors go ahead and hit resume on the right hand side and let's let's see if this works before we perhaps make it more complicated so hit the live preview button and let's do eight and i'm gonna go ahead and hit plus we're gonna say nine and that did not work so let's see equals 97 so that is not correct so let's try that one more time eight and when i go ahead and hit plus it should it should set the value to be zero again which it looks like we're not doing so what i'm going to go ahead and do is at the bottom of this we can say if the button doesn't equal if the button doesn't equal type of button equal we're going to go ahead and say self.value gets reset to be zero let's try that one more time go ahead and stop the live preview build and go ahead and do that we might need to hit resume a few times here so the simulator or our canvas updates we're gonna do eight plus goes back to zero perfect nine 8 plus 9 equals 17 which is correct so it looks like that's working let's try to add to this so we're going to say plus 3 17 plus 3 is 20. boom look at that let's try some more complicated ones uh 81 divided by uh what the heck happened there uh yeah it should be zero okay that's correct 81 divided by nine is going to be nine all right that's good let's do five seven eight nine six uh divided by three hundred and twenty one i have no idea this is going to be correct i'm gonna assume that's right one of you guys watching can check and tell me if i'm wrong with the comments so this is all looking good and it looks like the running calculation also works because we're basically holding on to the prior value so if i keep adding let's say a two to this should keep going up by two which it in fact is let's see if zeros are working so one problem i can think of is what happens if we keep clicking zero i guess we can't do that because it works by design but let's see if i do two zero zero zero looks like that works so for the most part we have most of our edge cases covered i'm sure there's a certain things we need to fix like this text rolling over but that's basically a calculator in a nutshell for the most part it's like 150 lines the one part i do want to review super quick is the actual calculation so our view should be fairly straightforward for everybody we basically have a horizontal stack up here for the actual text display we're using a z stack for the black color a vertical stack with two for loops for our buttons here in the actual function to tap a button we're basically switching on the type of button and if it's a operation type we basically hold on to the type of operation as well as the current value because that's the value we're going to apply the operation to in this case adding or subtracting or multiplying dividing and if the user hits equal all we go ahead and basically do is uh grab the current value and apply that operation to it so we're gonna either add subtract you know divide or multiply down below if the user hits clear we just clear out the value pretty simple and this default is all the numbers so whenever any of these numbers get hit if the value is zero we're gonna go the current value is zero we're gonna go ahead and just uh assign value to be whatever the input number is otherwise we're gonna tack on the number so keep in mind that tacking on the number isn't adding it right so in a calculator you should be adding the number to the right most of the number you see here that's why we ended up using a string to hold the value because it's kind of easier than you know doing the math of the number other than that we have our calculations for the button height and width and what we basically do here is take the width of the screen uh subtract the padding between each of the columns and then divide it by the number of columns we have we have a special case for zero because zero takes up two columns plus of the padding for two of those columns and actually one thing you can do to make sure this works is we can change our simulator drop down to let's try something smaller like an iphone 8 and see if that looks correct and you know if it ends up not looking correct you can always go back and uh you know tweak it to make sure that everything works so let's try that one more time because our preview is not cooperating all right there it goes i think it looked correct i just saw it all right bear with it let's try that one more time all right looking good so there is our iphone 8. one thing you might want to adjust is the bottom of uh the calculator here is kind of close to the edge of the screen but yeah our calculator is definitely working i'm going to put this code up on github thank you so much for watching uh hopefully this was a good primer in the swift ui not too complicated um take a look at the code on github it's a really good place to get started with the calculator app if you're new to the channel and have it hit the subscribe button yeah definitely do so to stay up to date with ios and swift videos definitely smash that like button if you forgot to do that so far thanks again for watching looking forward to seeing you guys here on the channel for the next videos thanks for watching again i'll see you in the next one you
Info
Channel: iOS Academy
Views: 12,649
Rating: undefined out of 5
Keywords: swiftui calculator, swiftui for beginners, learn swiftUI, swiftUI tutorial, calculator swiftui, calculator swift, building calculator, how to build calculator swift, swiftUI 2 calculator, 2021 swift calculator, swift for beginners, swiftui calculator 2021, building swift app, swiftUI beginner, swiftUI tutorial 2021, swiftUI calculator for beginners, beginners ios swift, swift stacks, swiftUI buttons, swift programming, swift 5, xcode 12 swift, xcode 12, swift example
Id: cMde7jhQlZI
Channel Id: undefined
Length: 33min 56sec (2036 seconds)
Published: Fri Mar 05 2021
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.