0

We are using UICollectionView to draw a calendar. The supplementary view is used for the date at the top of a column that represents a day in the calendar. Each calendar is a section in the UICollectionView. We want the current day highlighted. We have that working by

func collectionView(_ collectionView: UICollectionView, viewForSupplementaryElementOfKind kind: String, at indexPath: IndexPath) -> UICollectionReusableView {

    var view: UICollectionReusableView?
    if kind == WeeklyCollectionElementKindDayColumnHeader {
        let dayColumnHeader: WeeklyDayColumnHeader? = collectionView.dequeueReusableSupplementaryView(ofKind: kind, withReuseIdentifier: WeeklyDayColumnHeaderReuseIdentifier, for: indexPath) as? WeeklyDayColumnHeader
        let day: Date? = collectionViewCalendarLayout?.dateForDayColumnHeader(at: indexPath)
        let currentDay: Date? = currentTimeComponents(for: self.collectionView!, layout: collectionViewCalendarLayout!)
        let startOfDay: Date? = Calendar.current.startOfDay(for: day!)
        let startOfCurrentDay: Date? = Calendar.current.startOfDay(for: currentDay!)
        dayColumnHeader?.day = day
        dayColumnHeader?.isCurrentDay = startOfDay == startOfCurrentDay
        view = dayColumnHeader
    }
    else if kind == WeeklyCollectionElementKindTimeRowHeader {
        let timeRowHeader: WeeklyTimeRowHeader? = collectionView.dequeueReusableSupplementaryView(ofKind: kind, withReuseIdentifier: WeeklyTimeRowHeaderReuseIdentifier, for: indexPath) as? WeeklyTimeRowHeader
        timeRowHeader?.time = collectionViewCalendarLayout?.dateForTimeRowHeader(at: indexPath)
        view = timeRowHeader
    }

    return view!
}

which with this

class WeeklyDayColumnHeader: UICollectionReusableView {
var day: Date? {
    didSet {
        var dateFormatter: DateFormatter?
        if dateFormatter == nil {
            dateFormatter = DateFormatter()
            dateFormatter?.dateFormat = "E d"
        }
        self.title!.text = dateFormatter?.string(from: day!)
        setNeedsLayout()
    }
}
var isCurrentDay: Bool = false {
    didSet {
        if isCurrentDay {
            title?.textColor = UIColor.white
            title?.font = UIFont.boldSystemFont(ofSize: CGFloat(16.0))
            titleBackground?.backgroundColor = UIColor(red:0.99, green:0.22, blue:0.21, alpha:1.0)
        }
        else {
            title?.font = UIFont.systemFont(ofSize: CGFloat(16.0))
            title?.textColor = UIColor.black
            titleBackground?.backgroundColor = UIColor.clear
        }

    }
}

set the background we want the first time I come into this view. But if I have this view open and the date changes, how do I update the header? Where should I move the logic that sets the date, and how do I "invalidate" or whatever I need to do?

Jason Hocker
  • 6,879
  • 9
  • 46
  • 79
  • Date changes due to user interaction? – Barns Jun 30 '17 at 16:36
  • invalidate didn't seem to trigger redrawing the supplemental views. Is that a limitation or do I not have something wired correctly perhaps? – Jason Hocker Jun 30 '17 at 16:38
  • If you need to change the date due to user interaction (eg. user tapped cell) you need to implement the `didSelectItemAtIndexPath` method. – Barns Jun 30 '17 at 17:07
  • I want to change it based on the time change. The user has it open, and now the time moves past midnight. I want a header view to now appear different because it represents today. I need to take the background color off the previous one and add it to the right one – Jason Hocker Jun 30 '17 at 17:15

1 Answers1

0

Use the UIApplicationSignificantTimeChangeNotification in order to notify you of time changes.

Use the NotificationCenter to implement this. Something like this:

NotificationCenter.defaultCenter().addObserver(self, selector: "dayChanged:", name: UIApplicationSignificantTimeChangeNotification, object: nil)

Then you need a function to handle the change:

func dayChanged(notification: NSNotification){

    // trigger the changes you need here
}
Barns
  • 4,850
  • 3
  • 17
  • 31
  • In dayChanged, how do I redraw the section headers? – Jason Hocker Jun 30 '17 at 17:34
  • You will probably have a `IBOutlet` var for your collection view - maybe: `myCollectionView`. Then calling `myCollectionView.reloadData()` should do the trick. – Barns Jun 30 '17 at 17:39
  • For only reloading the headers you can use `collectionView reloadSections`. You will need to know the index range you want updated. – Barns Jun 30 '17 at 18:23