Search code examples
ioscocoa-touchuipickerview

How do you make an UIPickerView component wrap around?


I would like to show a set of consecutive numbers in a UIPickerView component but have it wrap around like the seconds component of the Clock->Timer application. The only behavior I can enable looks like the hours component of the Timer application, where you can scroll in only one direction.


Solution

  • It's just as easy to set the number of rows to a large number, and make it start at a high value, there's little chance that the user will ever scroll the wheel for a very long time -- And even then, the worse that will happen is that they'll hit the bottom.

    - (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component {
        // Near-infinite number of rows.
        return NSIntegerMax;
    }
    
    - (NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component {
        // Row n is same as row (n modulo numberItems).
        return [NSString stringWithFormat:@"%d", row % numberItems];
    }
    
    - (void)viewDidLoad {
        [super viewDidLoad];
    
        self.pickerView = [[[UIPickerView alloc] initWithFrame:CGRectZero] autorelease];
        // ...set pickerView properties... Look at Apple's UICatalog sample code for a good example.
        // Set current row to a large value (adjusted to current value if needed).
        [pickerView selectRow:currentValue+100000 inComponent:0 animated:NO];
        [self.view addSubview:pickerView];
    }
    
    - (void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component {
        NSInteger actualRow = row % numberItems;
        // ...
    }