How to use Timer and onReceive in SwiftUI | Continued Learning #24

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
what's up everyone i'm nick this is swiffle thinking and in this super exciting video we're going to look at the timer and the unreceived call in our swift ui views and it is exactly what it sounds like we're going to put a timer into our view and then every time that timer goes off we're going to do something on the screen so we're going to start off very simply by just putting the current time on the screen and every second it's going to update the time and then we're going to get into some more advanced ways how we can use timers to create custom animations to create custom features and it's going to be a whole lot of fun so of course we're going to start really simple but then we're going to get into a bunch of real world examples and i think you guys are going to really love this one and the reason i'm covering in this video in this section of the course is because although we don't need to import combine specifically we are using publishers and subscribers in the last video in this series we downloaded data from the internet using the combine framework and in that video i introduced you guys to publishers and as you're going to see a timer is actually a publisher it is an object that publishes values over time that's what a publisher is and then we're going to use the on receive call which is a really convenient swift ui function so that we can listen to that publisher also known as subscribing and we're going through this all because i feel like this is a very easy introduction to publishers and subscribers and in the next video we're going to actually take this a step further and create our own totally custom publishers and subscribers alright that's enough of me talking let's jump into xcode and set up some timers all right welcome back everyone i'm back in our xcode project of course and let's right click the navigator create a new file for this video let's make a swift ui view and let's call it timer boot camp go ahead and click create once you're inside click resume on the canvas i'm going to hide the navigator because we're not going to use it and let's get coding let's start out by creating a very simple screen we're going to create a z-stack open the brackets and i'm going to make a background just to make it look nice and pretty as we're coding so let's create a radial gradient because i taught gradients but i haven't been using them much and they look awesome in swift ui so radial gradient i'm going to put the gradient the center star radius all in separate lines so it's a little easier to read and let's just change up the colors quick let's do color let's use a color literal and i'm gonna double click on this and let's use maybe this second purple here and then let's do color color literal and i'm gonna use a darker shade so i'm gonna go down to maybe this one here i think that will look pretty cool uh let's keep it center radius 5 500 that's fine and let's just make it ignore the safe area so it goes to the edges of our screen and i love how nice this looks already with just one simple line of code but on top of the gradient let's add a simple text and let's just say hi for a second let's give this a font let's use the dot system and we'll use the size weight design i'm going to make this pretty big so let's do maybe 100. the weight i'll do semi-bold and the design let's do a different font that we don't normally use so let's do uh rounded that might look cool all right very simple screen here let's give it a foreground color of white let's give it a line limit of one so that it always stays on one line and a minimum scale factor of 0.1 so that if it gets too big it scales down to stay on one line if you're confused about anything so far i have done a video on gradients and a video on texts so let's keep moving forward here and the point of this video is to discuss timers so at the top of my view here i'm going to add a timer we're going to say let timer equals timer dot publish and when i look at this publish completion here we can see down here that it's going to return us a timer.timer publisher so let's click enter on that and again in the last video i introduced you guys to combine and in combine it's all about publishers and subscribers and although we don't have to actually import combine to use these timer publishers they are basically using the same logic we're creating a publisher that's going to publish values over time and then in a second we're going to subscribe to this publisher so that we can listen to it every time it publishes some information we can perform actions so very simply this timer we want to we wanted to publish every one second and the run loop we're going to press the period here and this is basically what thread we want to run on so we can run on the main thread or the current thread and this is going to be updating our ui so i'm going to use the main thread we can press the period here and there are a couple options you can read through these in your own time i pretty much just use common almost all the time so let's just do common and one thing we're going to add here is dot auto connect and this basically means it's just going to start this publisher this timer as soon as this screen loads so auto connect is just going to make the timer start publishing as soon as we initialize this view all right with this one very simple line of code we now have a timer on our screen but of course we're not doing anything with it so on our z stack here let's listen to this timer so we're going to call dot on receive and when we use this the on receive we need to pass in a publisher so this is any publisher in our app that is producing values that's publishing values and of course we have our timer so we're just going to pass our timer in here and when that publisher is publishing values we can actually get that value right here where this underscore is so i can put here a value so this is the value that's being passed in to the timer now i want to point out here that the value here is going to be based on the type that this publisher is publishing so this timer publisher publishes dates and that's we're going to get here but if we use a different publisher that maybe was publishing data or booleans or strings that's what would come through as this value so while this is a timer and this is a date let's just add a date onto the screen here so we're going to say so let's say at state var we'll say current date of type date and we'll set it equal to today's date for now this is when you use this in swift it's just the current exact date of right now so let's take this current date and call.description just to get it onto the screen quickly see what the text looks like all right and when this timer goes off every second because we have it at one second up here we just want to update the current date so i'm just going to set current date equal to the value that this timer is publishing if we click play on the simulator we can see it was that easy to actually get our time to update on the screen so every second this is updating and that was pretty simple and the main thing to really point out here is that here we set up a publisher that's going to publish values and then down here we are subscribing to the publisher so we're listening to that timer and every time it publishes a value we are performing an action now this is obviously a very simple implementation but let's take this a couple steps further just to get some use cases out of this timer so first of all this current date is good but i will touch on the date formatter because this doesn't look very pretty on our screen right now so let's add a var we'll call it date formatter it will be of type date formatter and then i will open the brackets and we're setting up with this open brackets because we're going to have because this is a computed property so we're going to do a little bit of logic to set this up so we're going to say let formatter equals a new date formatter open close parenthesis i'm going to say formatter dot let's do time style and let's set it equal to medium then we'll return the formatter zoom out here real quick and when we go to put this text on the screen let's actually use the date formatter dot string from and then we'll pass in the current date let's try it again now we have a nice formatted date it should look a little better beautiful 609 pm and fyi if you wanted to we could add the formatter here dot date style and then we can add in our date as well let's do medium now we have the date so you can obviously play around with this if you only wanted dates you could take out the time and we can do maybe dot full to get the entire time this is pretty cool but there's a lot more that we can actually do with this timer so let's actually comment some of this out and do another example so let's just call this current time i'm going to use the forward slash asterisks and then the asterix forward slash to make a multi-line comment and then i'm going to use the command option left arrow to fold up the code underneath this let's let's then do a countdown and for our countdown let's add an at state var let's call it count of type int and we'll set it equal to maybe 10 to start we'll do an at state var we'll say finished text of type string and we'll set it equal to nil sorry this should be an optional string all right for our text well let's get rid of this date formatter and we're going to say finished text and then since the finished text is optional uh if there is no finished text we'll use two question marks and we'll put in the count so we'll use the quotes to make it a string backslash open close parentheses and pass in the count and finally this on receive we're still going to look at the timer but we're not going to use the date value that actually comes out of it instead we're just going to perform some action every second so because we don't need that date i'm just going to make it back into an underscore and then in here let's put in a little bit of logic we're going to say if count is less than one open the brackets so if it's less than one let's add some finished text and it's done so we'll set finished text equal to wow we'll say else so if it's equal to or greater than one we'll say count minus equals one so we're going to subtract the count by one let's click resume on the canvas and now we have our very simple countdown going down from 10 all the way down to zero hopefully at zero we get our finished text and we saw the zero and then it said wow but let's actually just make it less than or equal to one so that we don't actually see the zero so just goes down to one and then finished text two one wow wow guys that was awesome and it was pretty simple to implement again we set up our publisher we listened to the publisher and then we performed an action let's take this to the next level because uh this counter this countdown was awesome but sometimes in your app you want to count down based on time it's a pretty common thing i've seen on stack overflow because a lot of apps right when you match or connect with someone maybe you have like one hour to perform a task or maybe you have 24 hours to do something well in that case you would want to put that countdown time on the screen so let's do that now so i'm going to make another multi-line comment here and i'm going to fold this up let's make another comment here i'm going to call this um countdown to date and let's do at state var let's call it time remaining of type string and let's set it to go to a blank string to start let's put that in our text we'll do time remaining and let's first set up the future date so if this person had maybe 24 hours left we'll say let future date of type date and we'll set it equal to calendar dot current this is the user's current local calendar dot date and we're going to type in adding and there's a super simple completion here date by adding a value to so we are going to add dot day and one so 24 hours to today's date and this is optional so we'll just do two question marks and for whatever reason if it doesn't work out we'll just put in today's date we know it's going to work out obviously but if this was your actual app you wouldn't be adding this this you probably wouldn't be setting up this date right here you'd probably have some logic somewhere in your app that was actually storing how much time was left or when the 24 hours completes and you would just put that as the future date for right now our future date is going to be 24 hours ahead of right now which is just one day ahead of right now and then we're going to create a function and normally i put the functions underneath the body but i'm just going to put this function above the body for this one section here we're going to say funk update time remaining open close parenthesis open the brackets and we're just going to call this function from the on receive so in here i'm just going to put update time remaining so every one second this function will get calls and for this function all we need to do is find out how much time is remaining between the current time and this future date so we'll say let remaining equals calendar dot current dot date components and we're going to look for the date components that have the from and to date here so from a start date and to an end date let's click enter and here we can create a set which is basically an array and we can press the period here and get all of the uh data that we want from this and so we're going to want the hours and maybe the minutes and maybe the seconds and the time remaining is from the current time right now so date to the future date all right i'll zoom out here just make it on one line and then we just want to get the hour the minute the seconds from how much is remaining so let's say let hour equals remaining dot hour and it's optional so if there is none left we'll put it as a zero we'll say let minute equals remaining dot minute otherwise zero and let second equals remaining dot second otherwise zero and then we will set the time remaining equal to a string and we're just going to pass in and we're just going to convert this hour minute seconds to a string here so we'll do backslash open close parenthesis we'll do hour and then let's add maybe a colon backslash open close parenthesis minute minute colon and then backslash open close parenthesis second and let's resume the canvas see what this looks like and hopefully we have our hour minute second on the screen so we set it to one day in advance which is 24 hours and we can see that our countdown is now going uh down from 24 hours down to our future date of course i could have changed this around so if instead of we wanted to add a day if we wanted to add maybe one hour we could click resume and we should get zero hours 59 minutes 50 54 seconds we could do more formatting here to make this like two zeros always or something like that but i'm not going to get into all that formatting because this is more focused on the timer but if we had this display with just minutes and seconds we might want to not use the hour so i'll just delete the hour and then maybe we would change up this string to be say minutes comma space and then seconds that might be more readable for our app here you can play around with it of course but the point here i'm getting across is that we can use this timer to count down to future date and we can also just call functions from within this timer so this is really helpful if you want to call any function every one second of course you could change the timing here so if you want this timer to go up every five seconds every 10 seconds all you need to do is change this number i want to show you two more really cool things i like to do with timers so let's forward slash asterix and then asterix forward slash and make this a multi-line comment and then fold it on up and one more let's make a comment here this will be an animation counter and here i'm just going to make an at state var we'll say count of type int and we'll set it equal to zero for this one we're not going to use text instead i'm going to make a h stack open the brackets i'm going to add a circle and i'm going to copy and paste this twice we have three circles and let's give it a foreground color of white i'm going to just get rid of this function here quickly click resume in the canvas see what we're working with we should just have three pretty big circles on the screen all right let's give this some spacing of maybe 15. let's give this a frame with a width of maybe 200 that looks good some of you probably know where i'm going with this already let's give these an offset and go down to the one with the x and the y and we're not going to use the x we're just going to use the y here and we'll say uh count if the count is equal to 1 let's give it an offset of 20. otherwise zero i'm going to copy this and paste it on both of my other circles and the second circle is going to be if the count is equal to two and the third one account is equal to three on the timer now we're just going to add one to the count so we'll say if count is equal to three so if it's at the max we're just going to reset count equal to zero else we'll say count plus equals one so so let's click resume on the canvas and actually this should be negative 20 sorry so negative 20. and let's click play on the simulator see if this is working it looks like it's working but let's make it a little more professional so this bit of code here i can actually put onto one line so we can do instead of all this we can say count equals if the count is equal to three question mark we'll put it at zero otherwise it'll be equal to count plus one so again this is the exact same code as this i'm going to delete this and for this code here i'm just going to do it with animation and i want to make this animation happen at the same timing as my timer so my timer my timer is going off every one second so down here i'm going to say dot ease in out and i'm going to use the duration of one second open the brackets let's put the count inside let's stop it let's press it play one more time and it just like that we now have a pretty cool loading animation i think we can make this look a little better so i'm going to stop the preview quickly let's make the width of this maybe 150 so it's a little smaller and then let's update the timer to maybe 0.5 seconds let's update the animation to also 0.5 and if i click play on the canvas it should be a pretty cool loading now animation course you can customize this and get this to be perfect but the fact that we can make this awesome loading animation in just a couple seconds using a timer i think is really really cool i want to wrap up with one more really cool example that i've used in apps i've seen it in apps and i've actually seen a couple of you requested in the comments so we are going to use the page tab view let's delete this h stack let's create a tab view and when we open the parentheses here let's use the selection and content press enter and the selection is going to be binding to our count and for the content i'm going to add just a rectangle open close parentheses and let's just give it a tag of one i'm going to also give this a foreground color of red and then i'm just going to copy and paste this a couple times so we have a bunch here let's make this one blue we'll give it a tag of two we'll do green give it a tag of three so when we tag a four tag of five let's change up the colors orange let's do maybe um pink and of course when you do this in your app this rectangle is not gonna be a rectangle it's gonna be your own custom view or an image that you want to show and when you do it you should probably do a for each loop on some data and not just add these rectangles five or six times but we're just doing this for simplicity sake on the tab view let's give this a dot tab view style and we'll use page tab view style open close parenthesis and on this let's also give this a frame with a height of maybe 200. all right so if you've seen maybe on like tick tock or something there's a lot of apps now where they have like this header on top of maybe the explore page and then there's an advertisement or a picture in it and then you can swipe it to the right and you can get all the and you can see all the different pictures but we're just going to animate it on a timer so we have five here so let's just change the timer logic to five and we don't need it to animate exactly in sync so instead of just easing out let's just use dot defaults and because we want the user to actually look at this picture for a couple seconds let's make it change every maybe three seconds in reality that's still probably fast for your app but let's press resume and adjust press play on the simulator see what it looks like quick press play and now every three seconds this should animate and we go to the second screen we go to the third screen we go to the fourth screen we go to the fifth screen and then on the fifth screen it should go back to zero awesome and i think we should actually start at number one for this just to make it better so let's start this at one let's start this at one and um i think we now have a working carousel here where we could put in a bunch of pictures or some really cool content and yeah so that was not a lot of lines of code to get something like this to be happening in your app which obviously gives a really great user experience the one thing i want you guys take away from this video isn't actually the timer itself but the fact that this timer up here is actually a publisher so we're creating a object up here that's going to continually publish values over time so obviously it's easy to think about when we're using a timer because every three seconds it's publishing a value but we can actually create our own custom publishers that will publish values maybe not every three seconds but over time and then after creating a publisher we can subscribe to the publisher so we used on receive here to listen to that publisher and then perform an action every time something gets published and i did this video first because in the next video we're going to actually create some more custom publishers and custom subscribers so it's going to be a whole lot of fun i hope you guys enjoyed this video as always i'm nick this is swiffle thinking and i'll see you in the next video [Music]
Info
Channel: Swiftful Thinking
Views: 2,581
Rating: undefined out of 5
Keywords: SwiftUI Timer, Timer SwiftUI, onReceive SwiftUI, SwiftUI onReceive, SwiftUI timers, SwiftUI Timer not starting, SwiftUI timer not working, how to use Timer SwiftUI, how to implement Timer SwiftUI, SwiftUI publishers, SwiftUI timer publisher, SwiftUI listen to publisher, SwiftUI subscribe to timer, SwiftUI listen to Timer, SwiftUI timer animation, SwiftUI animation with Timer, SwiftUI loading animation, custom Timer SwiftUI, SwiftUI how to use timer, timer animation SwiftUI
Id: ymXRX6ZB-J0
Channel Id: undefined
Length: 26min 16sec (1576 seconds)
Published: Tue Apr 27 2021
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.