1

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

edie
  • 758
  • 1
  • 11
  • 29
  • You want to make it circular? I'm trying to find an answer, check back later maybe I'll have figured it out. – mk12 Aug 18 '09 at 03:23
  • See http://stackoverflow.com/questions/214441/how-do-you-make-an-uipickerview-component-wrap-around – squelart Aug 18 '09 at 03:50

2 Answers2

5

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!
mk12
  • 25,873
  • 32
  • 98
  • 137
  • Thanks for the response. But does it will create 1000000 rows, and if I add UIImages to this row does it will create memory/performance issue. – edie Aug 18 '09 at 06:31
  • 1
    Only the rows that are visible will be loaded, and the cells/rows/whatever they're called for UIPickerViews should be reused, I believe. – T . Aug 18 '09 at 11:58
  • 1
    Actually, the performance will be exactly the same (unless you count the calculation of row%[pickerData count] as a performance hit). – mk12 Aug 20 '09 at 01:44
0

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.

Dan Lee
  • 101
  • 1
  • 5