iosswiftsegueviewcontrollerfscalendar

FSCalendar - create segue from day selected to another view controller


I am a beginner in writing iOS apps and am currently working on a calendar app using FSCalendar. I want my app to go to the next view controller whenever I tap on the selected day on the FSCalendar (to show details about events on the selected day) but I couldn't find a way to create a segue that connects from the selected day to the view controller.

If segue is the way to go in this case, how do I make one? But if segue isn't the way to do it, please give some suggestions of other possible solutions. Thank you in advance!


Solution

  • FSCalendar has a "did select date" delegate function. If you are looking at the Swift Storyboard Sample, it is called and prints a formatted date to the debug console. That's where you can trigger your segue.

    Start by adding a "Detail" view controller class:

    //
    //  DetailViewController.swift
    //  FSCalendarSwiftExample
    //
    //  Created by Don Mag on 8/31/20.
    //
    
    import UIKit
    
    class DetailViewController: UIViewController {
    
        var selectedDate: Date?
        
        @IBOutlet var myLabel: UILabel!
        
        fileprivate let formatter: DateFormatter = {
            let formatter = DateFormatter()
            formatter.dateFormat = "yyyy/MM/dd"
            return formatter
        }()
    
        override func viewDidLoad() {
            super.viewDidLoad()
    
            if let d = selectedDate {
                myLabel.text = formatter.string(from: d)
            }
        }
    
    }
    

    Add a view controller to the Storyboard with a couple labels, set its class to DetailViewController, and connect the "Detail Label" to the myLabel @IBOutlet:

    enter image description here

    Ctrl-Drag from the view controller icon at the top of the FSCalendar view controller to your new Detail View Controller, and select Show from the popup menu:

    enter image description here

    You'll see that a segue has been added. Select that segue and give it an identifier of "gotoDetail":

    enter image description here

    In InterfaceBuilderViewController class, find this func:

    func calendar(_ calendar: FSCalendar, didSelect date: Date, at monthPosition: FSCalendarMonthPosition) {
        print("calendar did select date \(self.formatter.string(from: date))")
        if monthPosition == .previous || monthPosition == .next {
            calendar.setCurrentPage(date, animated: true)
        }
    }
    

    and add a performSegue line at the end:

    func calendar(_ calendar: FSCalendar, didSelect date: Date, at monthPosition: FSCalendarMonthPosition) {
        print("calendar did select date \(self.formatter.string(from: date))")
        if monthPosition == .previous || monthPosition == .next {
            calendar.setCurrentPage(date, animated: true)
        }
        // add this line
        self.performSegue(withIdentifier: "gotoDetail", sender: nil)
    }
    

    still in InterfaceBuilderViewController class, find the prepare(for segue... func:

    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        if let config = segue.destination as? CalendarConfigViewController {
            config.lunar = self.lunar
            config.theme = self.theme
            config.selectedDate = self.calendar.selectedDate
            config.firstWeekday = self.calendar.firstWeekday
            config.scrollDirection = self.calendar.scrollDirection
        }
    }
    

    and add this code at the end:

    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        if let config = segue.destination as? CalendarConfigViewController {
            config.lunar = self.lunar
            config.theme = self.theme
            config.selectedDate = self.calendar.selectedDate
            config.firstWeekday = self.calendar.firstWeekday
            config.scrollDirection = self.calendar.scrollDirection
        }
        // add this code
        if let detail = segue.destination as? DetailViewController {
            detail.selectedDate = calendar.selectedDate
        }
    }
    

    Run the app, select Interface Builder from the table view, and select a date. Your new Detail controller should be pushed into view, and it should display your selected date.