Question

Can anyone help me how to make the UIPickerView displays the first row's value after the last row's value, just like the UIDatePicker where after 12 the 1 will follow.

Thanks

Was it helpful?

Solution

I don't think its possible to really make it circular, but you can fake it.

#define kRowsInPicker 10000

- (void)viewDidLoad {
    NSArray *localPickerData = [[NSArray alloc] initWithObjects:
                                @"Ottawa", @"Toronto", @"Montreal", @"Winnipeg",
                                @"Saskatchewan", @"Iqaluit", @"Edomonton", nil];
    [self setPickerData:localPickerData];
    [localPickerData release];

    UIPickerView *localPicker = [[UIPickerView alloc] initWithFrame:
                                 CGRectMake(0, 0, 320, 216)];
    [localPicker setDelegate:self];
    [localPicker setDataSource:self];
    localPicker.showsSelectionIndicator = YES;
    NSInteger  selectedRow = 0;
    [localPicker selectRow:(((NSInteger)((kRowsInPicker / 2) / [pickerData count])) * [pickerData count]) + (selectedRow%[pickerData count]) inComponent:0 animated:NO];
    [self setPicker:localPicker];
    [localPicker release];

    [[self view] addSubview:picker];
    [super viewDidLoad];
}
#pragma mark -
#pragma mark UIPickerViewDataSource methods

- (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView {
    return 1;
}

- (NSInteger)pickerView:(UIPickerView *)pickerView
                                numberOfRowsInComponent:(NSInteger)component {
    // usually "return [pickerData count];"
    return kRowsInPicker; // 10,000 is good, if you add a few more zeros
                          // there seems to be problems.
}

#pragma mark -
#pragma mark UIPickerViewDelegate methods

- (NSString *)pickerView:(UIPickerView *)pickerView
             titleForRow:(NSInteger)row forComponent:(NSInteger)component {
    return [pickerData objectAtIndex:row%[pickerData count]];
}

You can change the number of strings in pickerData and it will still work fine. The selected row selects the "first" value closest to the middle. row%[pickerData count] returns the following assuming there are 3 NSStrings in pickerData:

ROW             RETURNS
 0                0
 1                1
 2                2
 3                0
 4                1
 5                2
 6                0
 7                1
 8                2
 etc...
It will just cycle 0 through the length of the array. The confusing stuff in viewDidLoad just picks a value as close to the middle as possible using the index of the item of the array you provide in selectedItem. There is no performance hit or memory leak, all you have allocated is the single array. Whenever you access their selected choice, use ([localPicker selectedRowInComponent:0]%[pickerData count]). If there's something you don't understand or something I missed, please comment. Hope this helped!

OTHER TIPS

I have made a cyclic tableView based on UIScrollView. And based on this tableView, I re-implement UIPickerView. You might be interested in this DLPickerView. And this picker view has all the features that UIPickerView has, but also gives many new features, and custom this picker view is much easier.

https://github.com/danleechina/DLPickerView

And be aware of that this DLPickerView cyclically scroll is really scrolling cyclically. All the magic happened because of another class DLTableView.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top