Plot Generator:
UIPickerView, UIPickerViewDataSource, UIPickerViewDelegate

The Official Movie Plot Generator
by the Brothers Heimberg: Justin and Jason

Source code in Plot.zip

  1. main.m
  2. Class PlotAppDelegate
  3. Class Model
  4. Class ViewController
  5. Class View

The model (as in MVC)

The model, in class Model, consists of an array containing three smaller arrays: subject, predicate, and modifier. Each of these smaller arrays is an array of strings. A string that forms the first line of a multi-line selection is marked with a leading @.

The view

The View object contains an array of three UIPickerView objects. A UIPickerView looks like a UIDatePicker, but is not limited to picking dates. See Picker in the Human Interface Guidelines. By default, a UIPickerView is as wide as the view that contains it, and is 216 pixels high. I scaled each UIPickerView to one-third of the height of the View. The width of each UIPickerView was engineered so that after the scaling, it will be exactly as wide as the View.

Each column of a UIPickerView is called a component. Our UIPickerViews have only one component each. Each selection is 1, 2, or 3 lines of text, and we allow the UIPickerView to settle down only on the first line of a selection.

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.

The controller

The model and the view do not send each other messages directly. They talk to the ViewController. The ViewController creates the model and the view. (I thought the application delegate was too lofty to create the model.)

One problem. The address of a picker view is passed to its data source and delegate. But the picker views are subviews inside the View object, and only the View object knows about them. The addresses of the picker views would be meaningless to any object except the View object. The View object therefore had to be the data source and the delegate.

I wanted the ViewController to act as the data source and the delegate. And in a very real sense it does fulfill these rôles. Each data source and delegate method of the View receives one of three possible addresses. It changes the address into one of three possible numbers (0, 1, or 2) and then passes the number to the corresponding method of the ViewController. The ViewController uses these numbers when it sends messages to the Model.

Things to try

  1. Initialize the picker views to random positions at the start of the app.

  2. Each subject is currently an array of 1, 2, or 3 strings. A subject should also contain a number (or an “enumeration”) to let the predicate agree with the subject. 0 for male, 1 for female, 2 for plural. Create a class named Subject that will contain two instance variabless:
    	NSArray *lines;	//an array of 1, 2 or 3 NSStrings
    	int agree;	//0 for male, 1 for female, 2 for plural
    
    Each predicate is currently an array of 1, 2, or 3 strings. Change it to an array of three arrays (male, female, plural), each of which contains 1, 2, or 3 strings. When a male subject is selected, reloadAllComponents of the middle UIPickerView.

  3. Make it play a clicking sound as the wheels turn.