Quick tutorial - How to setup the calendar

Note: If at any point in this tutorial, you believe that you have already grasped the concept, then you can drop out at any time 👍


JTAppleCalendar is similar to setting up a UITableView with a custom cell.

calendararchitecture

There are two parts: The Cell, and the CalendarView

1. The cell

Like a UITableView, the cell also has 2 sub-parts: a xib file, and a class.

Click on (XCode 8) File -> New -> File -> View

screen shot 2016-10-04 at 2 52 19 pm

Let’s save this as CellView.xib.

Your view may look very large, so to make it smaller, click on the View -> then attributes inspector, and change the size to freeform as shown in the image below. Then adjust the size to something smaller

Drag a UILabel unto the view. And then position it using autolayout constraints. If you forget to use autolayout constraints, then your cell will not display properly.

cellxib

Paste the following code inside your new class.

import JTAppleCalendar 
class CellView: JTAppleDayCellView {
    @IBOutlet var dayLabel: UILabel!
}

Now let’s head back to your cellView.xib file and make the outlet connections.

setupinstructions

2. The calendarView

Paste this code in your ViewController class

import JTAppleCalendar
class ViewController: UIViewController {
    @IBOutlet weak var calendarView: JTAppleCalendarView!
}

After pasting the above code, do not forget to now connect this outlet to the JTAppleCalendarView on storyboard.

Whats next?


Similar to UITableView protocols, your ViewController has to conform to 2 protocols for it to work

Setting up the DataSource

The data-source protocol method is manditory. Let’s set this up now on your ViewController class.

I prefer setting up my protocols on my controllers using extensions to keep my code neat, but you can put it where ever you’re accustomed to.

The data-source protocol has only one function which needs to return a value of type ConfigurationParameters. This value requires 7 sub-values.

Paste the following code in your project.

extension ViewController: JTAppleCalendarViewDataSource, JTAppleCalendarViewDelegate {
    func configureCalendar(_ calendar: JTAppleCalendarView) -> ConfigurationParameters {
        let formatter = DateFormatter()
        formatter.dateFormat = "yyyy MM dd"
        
        let startDate = formatter.date(from: "2016 02 01")! // You can use date generated from a formatter
        let endDate = Date()                                // You can also use dates created from this function
        let parameters = ConfigurationParameters(startDate: startDate,
                                                 endDate: endDate,
                                                 numberOfRows: 6, // Only 1, 2, 3, & 6 are allowed
                                                 calendar: Calendar.current,
                                                 generateInDates: .forAllMonths,
                                                 generateOutDates: .tillEndOfGrid,
                                                 firstDayOfWeek: .sunday)
        return parameters
    }
}

The parameters should be self explainatory. The only ones that might be unfamiliar to you are: in-dates and out-dates. The following diagram will bring you up to speed.

Now that JTAppleCalendar knows its configuration properties, it is ready to start displaying dateCells. Let’s setup up the delegate protocol method to allow us to see the beautiful date cells we have designed earlier.

Add the following code to your extension.

    func calendar(_ calendar: JTAppleCalendarView, willDisplayCell cell: JTAppleDayCellView, date: Date, cellState: CellState) {
        let myCustomCell = cell as! CellView
        
        // Setup Cell text
        myCustomCell.dayLabel.text = cellState.text
        
        // Setup text color
        if cellState.dateBelongsTo == .thisMonth {
            myCustomCell.dayLabel.textColor = UIColor.black
         } else {
            myCustomCell.dayLabel.textColor = UIColor.gray
         }
    }

Important: cache your colors in a real app else your calendar will be laggy. The above code is for demonstration only. Just like in UITableView, this function will be called for every cell displayed on screen so be effecient with this code.

Your cell now has the ability to display text and color based on which month it belongs to. One final thing needs to be done. The Calender does not have its delegate and datasource setup. In your ViewController class,

paste the following code:

@IBOutlet weak var calendarView: JTAppleCalendarView! 
override func viewDidLoad() {
    super.viewDidLoad()
        calendarView.dataSource = self
        calendarView.delegate = self
        calendarView.registerCellViewXib(file: "CellView") // Registering your cell is manditory
    }
}

Completed! Where to go from here?


Well if you followed this tutorial exactly, then your calendar should look like this.

unimpressivecal

If your display does not look like this then:

  1. Did you remember to set autolayout constraints?
  2. Is your view shifted off the screen? Look at a solution here. Shifting often occurs if you put your calendar inside of a UINavigationController.

Pretty unimpressive… :/ Since I am not that great of a designer yet, I will copy what one of the users of this framework has done with this calendar control here. Click on that link and scroll down till you see the purple calendar. That’s the one we’ll attempt to make.

Setting up the color


Let’s cheat a bit. Paste this code anywhere in your project. I’ll put it in the ViewController.swift file.

// Paste the code outside of the ViewController class
class ViewController: UIViewController {
...
...
}

extension UIColor {
    convenience init(colorWithHexValue value: Int, alpha:CGFloat = 1.0){
        self.init(
            red: CGFloat((value & 0xFF0000) >> 16) / 255.0,
            green: CGFloat((value & 0x00FF00) >> 8) / 255.0,
            blue: CGFloat(value & 0x0000FF) / 255.0,
            alpha: alpha
        )
    }
}

This code allows us to create UIColors from Hex codes.

Head over to your CellView.xib and change the root cell view background color to: #3A284C on interface builder. This is a dark color, so head over to the ViewController.swift file and change the colors.

Change:

  1. The UIColor.black to UIColor(colorWithHexValue: 0xECEAED)
  2. The UIColor.gray to UIColor(colorWithHexValue: 0x574865)

Your calendar will now look like this:

almostcompletecal

Lets get rid of the white spaces. By default, the calendar has a cell inset of 3,3. I may change this to 0,0 if enough of you complain. In your ViewController.swift file and add this line of code in your viewDidLoad()

    override func viewDidLoad() {
        super.viewDidLoad()
            self.calendarView.dataSource = self
            self.calendarView.delegate = self
            calendarView.registerCellViewXib(file: "CellView") // Registering your cell is manditory

            // Add this new line
            calendarView.cellInset = CGPoint(x: 0, y: 0)       // default is (3,3)
    }

Your calendar will now look like this:

completecal

Complete. Jump over to Part 2 of this tutorial.

Create all the other views on your xib that you need. Event-dots view, customWhatEverView etc. After designing the views on your xib, go create the functionality for it just like you did in the example above; where you created a UILabel and added the functionality to display it. You can literally create any custom thing with any custom functionality.

If you’re really out of ideas, using the same procedure above, why not try to create a background circular shaped SelectedView to appear when ever you tap on a date cell? You can also download the example project on Github and see the possibilities.