Date Pickers: classes UIDatePicker and NSDateFormatter

In portrait orientation, this app keeps the top edge of the date picker at the bottom edge of the status bar. In landscape orientation, the status bar is hidden and the the top edge of the date picker is at the top edge of the big white View.



The controls looked better in iOS 6:

A UIDatePicker is a view that looked like a solid, metallic Las Vegas slot machine in iOS 6. Now it looks like a rotating virtual force field. The clicking sound when you rotate it is not played on the iOS Simulator.

We usually initialize a view by passing a frame rectangle to init, but a UIDatePicker already has a default size of 375 × 216 pairs of pixels on iPhone 6 (undocumented). We could resize it with its transform property and CGAffineTransformMakeScale, but don’t. Everyone expects that the UIDatePicker will remain its natural size. We should specify only its position.

Source code in DatePicker.zip

  1. Class AppDelegate: unchanged.
  2. Class ViewController: unchanged.
  3. Class View: added three properties and the methods init, addViewControllerConstraint, and valueChanged. A subview must be added to its superview before the subview’s size and position can be constrained.

Things to try

  1. Try all four UIDatePickerModes:
    1. UIDatePickerMode.Time
    2. UIDatePickerMode.Date
    3. UIDatePickerMode.DateAndTime
    4. UIDatePickerMode.CountDownTimer

  2. By default, a date picker is initialized to the current date and time. Initialize it to a different date and time by changing the following statements in the init method of class View.
    		dateFormatter.dateStyle = NSDateFormatterStyle.FullStyle;
    		dateFormatter.timeStyle = NSDateFormatterStyle.FullStyle;
    
    to
    		//so we don't have to write the day of the week
    		//in the string in "December 31, 2014"
    		dateFormatter.dateStyle = NSDateFormatterStyle.LongStyle;
    
    		//so we don't have to write the time
    		//in the string in "December 31, 2014"
    		dateFormatter.timeStyle = NSDateFormatterStyle.NoStyle;
    
    		let date: NSDate? = dateFormatter.dateFromString("December 31, 2014")!;
    		if date != nil {
    			datePicker.date = date!;
    		}
    
    		//The output in the label should show day of week and time.
    		dateFormatter.dateStyle = NSDateFormatterStyle.FullStyle;
    		dateFormatter.timeStyle = NSDateFormatterStyle.FullStyle;
    
    Wednesday, December 31, 2014 at
    12:00:00 AM Eastern Standard Time
    

  3. Make a date picker with a minimumDate and a maximumDate.

  4. Change the date formatter’s dateStyle to NSDateFormatterStyle.NoStyle, and observe that the date is no longer printed. Similarly, change the timeStyle to NSDateFormatterStyle.NoStyle, and observe that the time is no longer printed. (If they’re both NoStyle, the word “at” won’t be printed either.) Knowing all of this, display the date in one label and the time in another label.

  5. Instead of printing the date we picked, print the date on which the baby is due. In the valueChanged method of class View, change
    		label.text = dateFormatter.stringFromDate(datePicker.date);
    
    to
    		let dueDate: NSDate = NSDate(timeInterval: 60 * 60 * 24 * 280, sinceDate: datePicker.date);
    		label.text = dateFormatter.stringFromDate(dueDate);
    

  6. See how the date picker animates away from February 30? Make it animate away from any date that is a Sunday. If the date is a Sunday, assign a different value to the date property of the date picker.
    		//In the valueChanged method of the view controller
    
    		let dateComponents: NSDateComponents =
    			datePicker.calendar.components(NSCalendarUnit.WeekdayCalendarUnit, fromDate: datePicker.date);
    
    		let i: Int = dateComponents.weekday;	//1 for Sunday, 2 for Monday, etc.
    		if i == 1 {
    			//Go to the day after the Sunday.
    			let monday: NSDate = NSDate(timeInterval: 60 * 60 * 24, sinceDate: datePicker.date);
    			datePicker.setDate(monday, animated: true);
    		}
    

  7. [Not an assignment.] Make a Jewish calendar date picker. Insert the following into the init method of class View immediately after creating the picker.
    		dateFormatter.calendar = NSCalendar(calendarIdentifier: NSHebrewCalendar);
    		datePicker.calendar = dateFormatter.calendar;
    		print("datePicker.calendar.calendarIdentifier = \(datePicker.calendar.calendarIdentifier)");
    
    datePicker.calendar.calendarIdentifier = hebrew