Eric
Eric

Reputation: 303

Swift 3 Set Date Range of Datepicker Programmatically

I want create a date picker programmatically with range from today to 6 days later, e.g. today, 7/14, ... 7/20.

The code likes below.

self.datePickerView = UIDatePicker(frame: CGRect(x: 0, y: 50, width: UIScreen.main.bounds.width, height: 180))

if let datePickerView = self.datePickerView {
    let currentDate: Date = Date()

     datePickerView.calendar = NSCalendar.current
     datePickerView.timeZone = NSCalendar.current.timeZone

     var beginComponents = DateComponents()
     beginComponents.day = 0
     datePickerView.minimumDate = Calendar.current.date(byAdding: beginComponents, to: currentDate)

     var endComponents = DateComponents()
     endComponents.day = 6
     datePickerView.maximumDate = Calendar.current.date(byAdding: endComponents, to: currentDate)

     dateSelectorView.addSubview(datePickerView)
}

The date picker shows not only the 7 days, but also past dates(e.g. 7/12) and future dates(e.g. 7/21). Is there any solution to just show the 7 days?

Thanks a lot in advance!!!

Upvotes: 0

Views: 4219

Answers (2)

samuel samer
samuel samer

Reputation: 311

    var datePicker: UIDatePicker = UIDatePicker()
    datePicker?.datePickerMode = .date
    datePicker?.minimumDate = Date() // this to set the start date today
    //this to set the date range you can change " byAdding: .year " to "byAdding: .month" if you went the range by month or to "byAdding: .day"
    let nextDays = Calendar.current.date(byAdding: .year, value: 14, to: Date()) 
    datePicker?.maximumDate = nextDays ?? Date() // this to set the maximum date

Upvotes: 1

SirCJ
SirCJ

Reputation: 515

It doesn't seem possible to change UIDatePicker I would suggest implementing a custom UIPickerView do to what you want.

Create an extension on Date and added a new method next(numberOfDays:from:) & helper method nextSevenDays()

extension Date { 

 static func nextSevenDays() -> [Date]{
   return Date.next(numberOfDays: 7, from: Date())
 }

 static func next(numberOfDays: Int, from startDate: Date) -> [Date]{
    var dates = [Date]()
    for i in 0..<numberOfDays {
        if let date = Calendar.current.date(byAdding: .day, value: i, to: startDate) {
        dates.append(date)
        }
    }
    return dates
    } 
}

Inside viewController set an array to hold the possible dates and to act as the dataSource

 class ViewController: UIViewController, UIPickerViewDelegate, UIPickerViewDataSource { 

  @IBOutlet weak var datePicker: UIPickerView!

  let availableDates: [Date] = {
    return Date.nextSevenDays()
   }

  // You'll need a DateFormatter to 'pretty print' the dates to the pickerView labels.
  lazy var dateFormatter: DateFormatter = {
      let df = DateFormatter()
      df.dateFormat = "EEEE, MMMM, dd, YYYY"
      return df
   }()

override func viewDidLoad() { 
 super.viewDidLoad() 
 self.datePicker.dataSource = self
 self.datePicker.delegate = self
}

 //Required Methods for UIPickerViewDataSource & UIPickerViewDelegate 

func numberOfComponents(in pickerView: UIPickerView) -> Int {
        return 1
    }

    func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
        return self.avaliableDates.count
       }

func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
    let label = dateFormatter.string(from: avaliableDates[row])
    return label
}

//Use this method to do work when a date is selected. 
func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {

    print(avaliableDates[row])
}

Upvotes: 1

Related Questions