Skip to content

Instantly share code, notes, and snippets.

@thomasdegry
Created April 23, 2015 04:29
Show Gist options
  • Save thomasdegry/d31a543f07a229db4302 to your computer and use it in GitHub Desktop.
Save thomasdegry/d31a543f07a229db4302 to your computer and use it in GitHub Desktop.
//
// WeekCollectionViewController.swift
// dot
//
// Created by LOANER on 4/21/15.
// Copyright (c) 2015 Thomas Degry. All rights reserved.
//
import UIKit
let reuseIdentifier = "weekCollectionViewCell"
class TestCollectionViewController: UICollectionViewController, UICollectionViewDelegateFlowLayout {
var fromDate:NSDate?
var toDate:NSDate?
var dayDate:NSDate = NSDate()
override func viewDidLoad() {
super.viewDidLoad()
calculateFromAndToDate()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
override func viewWillAppear(animated: Bool) {
self.collectionView?.reloadData()
}
override func viewWillLayoutSubviews() {
// Check if we need to append or prepend dates
if collectionView?.contentOffset.x < 0 {
// Create date components
let components = NSDateComponents()
components.weekOfYear = -2
// Do it!
self.shiftDatesByComponents(components)
} else if (collectionView?.contentOffset.x > (collectionView!.contentSize.width - CGRectGetWidth(self.collectionView!.bounds))) {
// Create date components
let components = NSDateComponents()
components.weekOfYear = 2
// Do it!
self.shiftDatesByComponents(components)
}
}
// MARK: - WeekCollectionView methods
func calculateFromAndToDate() {
var calendar = NSCalendar.currentCalendar()
// Get first day of this week
let weekdayComponents = calendar.components(.CalendarUnitWeekday, fromDate: self.dayDate)
let componentsToSubtract = NSDateComponents()
componentsToSubtract.day = -(weekdayComponents.weekday - calendar.firstWeekday)
// First day of the week
let beginningOfTheWeek = calendar.dateByAddingComponents(componentsToSubtract, toDate: self.dayDate, options: .allZeros)
// Till last monday
let components = NSDateComponents()
components.weekOfYear = -2
self.fromDate = calendar.dateByAddingComponents(components, toDate: beginningOfTheWeek!, options: .allZeros)
// Add 14 days, this week monday + 7 is next week monday + that week = 14
components.weekOfYear = 2
self.toDate = calendar.dateByAddingComponents(components, toDate: beginningOfTheWeek!, options: .allZeros)
self.collectionView?.reloadData()
}
func shiftDatesByComponents(components: NSDateComponents) {
// Get reference to collectionview and it's layout
let collectionView = self.collectionView!
let layout = collectionView.collectionViewLayout as? UICollectionViewFlowLayout
// Get the visible cells
let visibleCells = collectionView.visibleCells()
// Abort if no cells are visible
if (visibleCells.count == 0) {
return
}
// Get the first visible cell
let firstCell = visibleCells[0] as? WeekCollectionViewCell
// Get it's indexpath
let fromIndexPath = collectionView.indexPathForCell(firstCell!)
// First day in section
let dateForFirstSection = self.dateForWeekOfYearInSection(fromIndexPath!.section)
println("first day in section = \(dateForFirstSection)")
// Get from section origin
let fromLayoutAttrs = layout?.layoutAttributesForItemAtIndexPath(NSIndexPath(forItem: 0, inSection: fromIndexPath!.section))
let fromSectionOrigin = self.view.convertPoint(fromLayoutAttrs!.frame.origin, fromView: collectionView)
self.fromDate = NSCalendar.currentCalendar().dateByAddingComponents(components, toDate: self.fromDate!, options: .allZeros)
self.toDate = NSCalendar.currentCalendar().dateByAddingComponents(components, toDate: self.toDate!, options: .allZeros)
println("new from date = \(self.fromDate) and new to date = \(self.toDate)")
// collectionView.performBatchUpdates({ () -> Void in
//
// if components.weekOfYear < 0 {
// collectionView.deleteSections(NSIndexSet(indexesInRange: NSRange(location: collectionView.numberOfSections() - abs(components.weekOfYear), length: abs(components.weekOfYear))))
// collectionView.insertSections(NSIndexSet(indexesInRange: NSRange(location: 0, length: abs(components.weekOfYear))))
// } else {
// collectionView.insertSections(NSIndexSet(indexesInRange: NSRange(location: collectionView.numberOfSections(), length: abs(components.weekOfYear))))
// collectionView.deleteSections(NSIndexSet(indexesInRange: NSRange(location: 0, length: abs(components.weekOfYear))))
// }
//
// }, completion: { (finished) -> Void in
// println("finished batch update")
// })
//
// for view in collectionView.subviews {
// view.layer?.removeAllAnimations()
// }
collectionView.reloadData()
layout?.invalidateLayout()
layout?.prepareLayout()
let fromDate = self.dateForWeekOfYearInSection(0)
let toSection = NSCalendar.currentCalendar().components(NSCalendarUnit.CalendarUnitWeekOfYear, fromDate: fromDate, toDate: dateForFirstSection, options: .allZeros).weekOfYear
let toLayoutAttrs = layout?.layoutAttributesForItemAtIndexPath(NSIndexPath(forItem: 0, inSection: toSection))
let toSectionOrigin = self.view.convertPoint(toLayoutAttrs!.frame.origin, fromView: collectionView)
collectionView.setContentOffset(CGPoint(x: collectionView.contentOffset.x + (toSectionOrigin.x - fromSectionOrigin.x), y: collectionView.contentOffset.y), animated: false)
}
// MARK: UICollectionViewDataSource
override func numberOfSectionsInCollectionView(collectionView: UICollectionView) -> Int {
let components = NSCalendar.currentCalendar().components(NSCalendarUnit.CalendarUnitWeekOfYear, fromDate: self.fromDate!, toDate: self.toDate!, options: .allZeros)
return components.weekOfYear
}
override func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return 7
}
override func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCellWithReuseIdentifier(reuseIdentifier, forIndexPath: indexPath) as! WeekCollectionViewCell
// Get the cell's date based on the indexpath + components
let cellDate = self.dateFromStartDateWithIndexpath(indexPath)
// Set the cell's date
cell.cellDate = cellDate
let hue = (CGFloat(arc4random()) % 256 / 256)
let saturation = (CGFloat(arc4random()) % 128 / 256) + 0.5
let brightness = (CGFloat(arc4random()) % 128 / 256) + 0.5
let color = UIColor(hue: hue, saturation: saturation, brightness: brightness, alpha: 1)
cell.backgroundColor = color
return cell
}
// MARK: UICollectionViewDelegateFlowLayout
func collectionView(collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAtIndexPath indexPath: NSIndexPath) -> CGSize {
return CGSize(width: self.view.frame.width / 7, height: self.view.frame.height)
}
// MARK: - Helpers
func dateFromStartDateWithIndexpath(indexPath: NSIndexPath) -> NSDate {
// Figure out the cell's date
let components = NSDateComponents()
components.day = indexPath.row
components.weekOfYear = indexPath.section
// Calculate the cell date with the components
return NSCalendar.currentCalendar().dateByAddingComponents(components, toDate: self.fromDate!, options: .allZeros)!
}
func dateForWeekOfYearInSection(section: Int) -> NSDate {
let components = NSDateComponents()
components.weekOfYear = section
return NSCalendar.currentCalendar().dateByAddingComponents(components, toDate: self.fromDate!, options: .allZeros)!
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment