and its UIPickerViewDataSource and UIPickerViewDelegate

When you match a city with its state, the View’s background color will turn green. A UIPickerView had a “selection indicator” (a plastic shield) in iOS 6:

See Picker in the Human Interface Guidelines. By default, the dimensions of a UIPickerView on iPhone 6 are 375 × 216 pairs of pixels. You could scale a UIPickerView (and here’s an example), but don’t.

Each column of a UIPickerView is called a component. Our UIPickerView has 2 components, numbered from left to right starting at 0.

Source code in Picker.zip

  1. Class AppDelegate
  2. Class ViewController is also the UIPickerViewDataSource and the UIPickerViewDelegate.
  3. 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 the number of rows in each component. A UIPickerView must also have a delegate object, which provides it with the string (or picture) 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 often be the same object. For example, our ViewController acts as the data source and delegate of the picker view.

Output from print

The UIPickerView has the same dimensions as the UIDatePicker we saw here. 375 is the width of the iPhone 6 screen in portrait orientation.

pickerView.frame = (-187.5,-108.0,375.0,216.0)

Things to try

  1. In the init(viewController:) 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.
    		for var component = 0; component < pickerView.dataSource!.numberOfComponentsInPickerView(pickerView); ++component {
    			let n: Int = pickerView.dataSource!.pickerView(pickerView, numberOfRowsInComponent: component);
    			//Convert n from plain old Int to UInt32.
    			//Pick a random number in the range 0 to n-1 inclusive.
    			//Convert the random number from UInt32 to plain old Int.
    			let row: Int = Int(arc4random_uniform(UInt32(n)));
    			pickerView.selectRow(row, inComponent: component, animated: true);
    		if pickerView.selectedRowInComponent(0) == pickerView.selectedRowInComponent(1) {
    			backgroundColor = UIColor.greenColor();
    		} else {
    			backgroundColor = UIColor.redColor();
    Can we avoid having to write the if in two different places?

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