How to write an app -fitness tracker iOS version – creating a custom calendar part 2

In the previous post I went over how to create the basic layout of a custom calendar which displays a box with the date in the top for each day of the month, and within each box is a button that when clicked, can be set to display an image of our choosing. To go back and see how this layout was built click here…How to write an app – Fitness tracker IOS version – building a custom calendar

trackerc3

In this post I want to go over including some code in our app that will adjust the appearance of the calendar based on which month we are looking at, so for example when looking at September we will see 30 boxes instead of 31.

Logic tells us that no matter what month we are looking at, the first 28 days will always appear the same. For this reason, we need to create code that can make the 29th, 30th and 31st number labels and buttons disappear and reappear as we need.

So lets start by creating some IBOutlets for the number labels and buttons, so we can affect these with code. For those that don’t know, an IBOutlet is like a connection between an object on your storyboard and the code for your app. Let’s create the outlets to make this more clear.

Make sure you can see your main storyboard and your code for the main page and then select the number 29 label. Holding control, drag and drop underneath the “didReceiveMemoryWarning()” function code block. You should see an small window open up as below…

trackerd1

Make sure the connection type is “Outlet” and name it something appropriate. Here I’ve named it label29, and ensure the Type is correct, in this case UILabel. Once you press connect you should see the IBOutlet appear in your code as below.

trackerd2

So this now gives us the ability to write code that will take actions on this label. Which we will do whenever the user changes the month. Let’s now go ahead and create IBOutlets for the remaining number labels and buttons for days 29,30 and 31.

trackerd3

At this point we are now able to write code that takes actions on each of these objects. Specifically, if I write code to remove the text in both the label and the button, its as if they are not there as far as the user is concerned. I could put some code into the viewDidLoad function to test that this works, however I don’t want the labels to change on opening the app willy nilly, I want the labels to change depending on what month we are currently viewing.

This leads us to our first coding problem, how do we know what day we are currently viewing. For me it makes sense to always open the calendar on the current month we are in. Here is how I went about determining the current month. Within the ViewController class, before the viewDidLoad and other functions enter the following code…

let now = Date()

let dateFormatter = DateFormatter()

var nameOfMonth : String = “default”

Let’s explain whats going on here, the “let” keyword signifies a constant. The current date isn’t going to change while you are looking at the calendar (most likely) and so this can be a constant value. In this case, a “Date” object is created that will not change and signifies todays date.

Similarly, underneath we create a “DateFormatter” object that will not change. This formatter simply lets me take the date object and format it into a way that is easier to handle, this will become more obvious in a moment.

Finally, I create a String variable to hold the name of the month called “nameOfMonth”. Since this will change if the user changes the month they are looking at, this is not a constant and has been declared using var instead of let. As we do not yet know which month we are looking at, I have initialised the variable with the value “default”.

trackerd4

So at this point, we have a date object containing the current date, and a string variable currently with the value “default”. What I want to do now is change the nameOfMonth string to reflect the current date. Here’s the code to implement this followed by the explanation…

if(nameOfMonth == “default”){

            dateFormatter.dateFormat = “LLLL”

            nameOfMonth = dateFormatter.string(from: now)

}

The first line of code is the if statement. In case you’re wondering why we would need an if statement, its because later on in the app we build functionality that takes you to a different page, and when returning to the main page we might not necessarily want to set the month to the current month. The user may have scrolled across to a different month, and we want them to be able to return to the month they were currently viewing, not be taken back to the month of the current date (what a mouthful!)

So anyway, if the app has just been started and the current name of the month is “default” the if block is entered.  Then we set the date formatter to display the date as a single month in a text string using the “LLLL” value. To put into context a little how that works and what its doing, if I had set the value to “LLL” the output would be “Sep” for example, “LLLL” would give “September” and “YYYY” would give “2018”. For a full list of how you can format the date google dateformatter.dateformat.

And now finally, we apply the date formatter to the current date using the line of code, nameOfMonth =dateFormatter.string(from: now). What this leaves us with, is the nameOfMonth being for example, “September” or “October”

Having a variable with a limited set of possible values is great because we can now create a series of if else statements. Before going into the code the logic we want to create now is to say, if the month is x,y or z, set certain days to be visible or invisible. And if the date is a,b or c then set different days to be visible or invisible.

At this point, we’re not setting any code to let us change the month manually, we will do that in the next post. But the code we’re about to write will change the calendar to reflect the current month as determined by your phone. At the time of writing, it is October and so actually I wouldn’t expect this code to change anything as there are 31 days in the month, and all 31 days are visible by default.

I’m going to create a function called setDays(). This function will run through a series of if else blocks and make days visible or invisible as appropriate. There will be 3 blocks needed, as some months have 30 days, some have 31 and February has 28. See the code below for the full function…

trackerd6

Hopefully the code logic there is obvious, you can see I’ve forgotten to remove the comments to remind me of what code to put where, what an absolute bozo. So the only thing remaining to do is call the function setDays(). I put this in the viewDidLoad() function as I want it to be called when the view loads, when the app is opened.

So, thats that, a calendar that changes depending on what month it is when you open it. Hopefully you can imagine from here it’s a simple matter of changing the nameOfMonth variable and then calling setDays() again to change the calendar, but in any case the next post will go through this. Hopefully this has been helpful!

Advertisements

3 thoughts on “How to write an app -fitness tracker iOS version – creating a custom calendar part 2

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s