1

Im trying to build a weekly calendar for IOS.

It should look like this.

The problem with that sample is code is: the usage of an dates array

let dates = ["7/10/2017", "7/11/2017", "7/12/2017", "7/13/2017", "7/14/2017", "7/15/2017", "7/16/2017"]

func spreadsheetView(_ spreadsheetView: SpreadsheetView, cellForItemAt indexPath: IndexPath) -> Cell? {
    if case (1...(dates.count + 1), 0) = (indexPath.column, indexPath.row) {
        let cell = spreadsheetView.dequeueReusableCell(withReuseIdentifier: String(describing: DateCell.self), for: indexPath) as! DateCell

        cell.label.text = dates[indexPath.column - 1]

        return cell

Filling that array with real dates from 01.01.2000 - 31.12.2099 e.g. leads to really bad performance of the app.

Does anyone know how to display the current Dates in an more elegant way?

130
  • 57
  • 1
  • 7
  • 2
    Do you really need an array populated with roughly 36,500 dates? – rmaddy Nov 01 '17 at 16:15
  • I would love to do it in another more elegant way – 130 Nov 01 '17 at 17:39
  • The way to handle a situation like this is to load only the data needed either side of the displayed page, so at most the array need only hold three years worth of dates. You then refresh the array as the user swipes to the next page of dates. – sketchyTech Nov 01 '17 at 19:48

2 Answers2

1

You could do so by using the following extension:

See here : Swift: Print all dates between two NSDate()

extension Date{

func generateDatesArrayBetweenTwoDates(startDate: Date , endDate:Date) ->[Date]
{
    var datesArray: [Date] =  [Date]()
    var startDate = startDate
    let calendar = Calendar.current

    let fmt = DateFormatter()
    fmt.dateFormat = "yyyy-MM-dd"

    while startDate <= endDate {
        datesArray.append(startDate)
        startDate = calendar.date(byAdding: .day, value: 1, to: startDate)!

    }
    return datesArray
}
}

Usage:

let dates = Date().generateDatesArrayBetweenTwoDates(startDate: Your Start Date Object , endDate: Your End Date Object)
Casey West
  • 578
  • 5
  • 22
1

Here's one solution using Calendar enumerateDates:

// 01.01.2000
let startComps = DateComponents(year: 2000, month: 1, day: 1)
let startDate = Calendar.current.date(from: startComps)!
// 31.12.2099
let endComps = DateComponents(year: 2099, month: 12, day: 31)
let endDate = Calendar.current.date(from: endComps)!

let components = DateComponents(hour: 0, minute: 0, second: 0) // midnight
var dates = [startDate]
Calendar.current.enumerateDates(startingAfter: startDate, matching: components, matchingPolicy: .nextTime) { (date, strict, stop) in
    if let date = date {
        if date <= endDate {
            dates.append(date)
        } else {
            stop = true
        }
    }
}
rmaddy
  • 314,917
  • 42
  • 532
  • 579