and its UIPickerViewDataSource and UIPickerViewDelegate

See Picker in the Human Interface Guidelines. By default, a UIPickerView is as wide as the view that contains it, and its height is 216 pixels (or pixel pairs) in portrait orientation, 162 in landscape. You could scale a UIPickerView (and here’s and example), but don’t.

Each column of a UIPickerView is called a component. Our UIPickerView has 2 components.

Source code in Picker.zip

  1. main.m
  2. Class PickerAppDelegate
  3. Class ViewController is also the UIPickerViewDataSource and the UIPickerViewDelegate
  4. Class View

The data source and the delegate

Every UIPickerView must have a data source object, which provides it with the number of components and rows in each component. A UIPickerView must also have a delegate object, which provides it with the string to be displayed in each row. (Isn’t it strange that the method pickerView:titleForRow:forComponent: belongs to the delegate, not the data source?) The data source and the delegate will usually be the same object. For example, our ViewController acts as the data source and delegate of the picker view.

Output from NSLog

2013-08-09 19:39:55.635 Picker[42024:c07] initWithFrame: frame.origin = (0, 0)
2013-08-09 19:39:55.636 Picker[42024:c07] initWithFrame: frame.size = 320 × 216

Things to try

  1. In the initWithFrame: method of the View, initialize the components of the picker view to random positions by calling the selectRow:inComponent:animated: method of the picker view.

  2. Observe that the picker view does not resize when we change the iPhone’s orientation to landscape. To make it resize, add the following method to class View. We saw this method here.
    - (void) layoutSubviews {
    	pickerView.frame = CGRectZero;
    	CGRect frame = pickerView.frame;
    	NSLog(@"initWithFrame: frame.origin = (%g, %g)",
    		frame.origin.x, frame.origin.y);
    	NSLog(@"initWithFrame: frame.size = %g × %g",
    		frame.size.width, frame.size.height);
    2013-08-09 19:53:01.840 Picker[49174:c07] initWithFrame: frame.origin = (0, 0)
    2013-08-09 19:53:01.841 Picker[49174:c07] initWithFrame: frame.size = 480 × 162
    The method gives the warning
    2013-08-09 19:52:31.251 Picker[49174:c07] -[UIPickerView setFrame:]:
    invalid height value 0.0 pinned to 216.0 

  3. A Las Vegas picker view should contain pictures (cherry, apple, lemon) instead of strings. See pickerView:viewForRow:forComponent:reusingView:.