问题
As seen in UIDatePicker you can scroll up endlessly (as well as down for that matter). I want to accomplish that too, because I want people to select a date such as:
1 January, 2010 2 January, 2010 ... 30 December, 2010 31 December, 2010 1 January, 2011 ..
So it can go on forever. How would I accomplish this? Since I can only give a specific amount of rows in the delegate.
回答1:
I don't think you can actually make the UIPickerView loop, but the way I've done it in the past is to return a really large number from numberOfRowsInComponent
and then calculate the modulus of the row to return the appropriate view from viewForRow
, like this:
// picker data source:
-(NSInteger) pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger) component
{
// to make it look like the picker is looping indefinetly,
// we give it a really large length, and then in the picker delegate we consider
// the row % (actual length) instead of just the row.
return INT16_MAX;
}
// picker delegate:
-(UIView *) pickerView:(UIPickerView *)pickerView viewForRow:(NSInteger) row forComponent:(NSInteger) component reusingView:(UIView *)view
{
// to make it look like the picker is looping indefinetly,
// we give it a really large length in the picker data source, and then we consider
// the row % actual_length instead of just the row.
row = row % actual_length;
// where actual length is the number of options that will be looping
// ... do whatever
}
and in your initialization:
- (void)viewDidLoad {
[super viewDidLoad];
// ... whatever other initialization...
// to make it look like the picker is looping indefinetly ,
// we give it a really large length in the picker data source, and then we consider
// the row % actual_length instead of just the row,
// and we start with the selection right in the middle, rounded to the
// first multiple of actual_length so we start the selection on
// the first option in the list.
[myPicker selectRow:(INT16_MAX/(2*actual_length))*actual_length inComponent:0 animated:NO];
}
回答2:
I agree with most of the above (filipe) answer, just one thing: yes you can make the UIPickerView loop:
- (void)viewDidLoad
{
[super viewDidLoad];
[myPicker selectRow:(INT16_MAX/(2*actual_length))*actual_length inComponent:0 animated:NO];
}
-(NSInteger) pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger) component
{
return INT16_MAX; // Just some big number
}
-(UIView *) pickerView:(UIPickerView *)pickerView viewForRow:(NSInteger) row forComponent:(NSInteger) component reusingView:(UIView *)view
{
row = row % actual_length; // This is the value you should use as index of your data
// And here comes the trick, move the wheel back again to the middle rows
// so the user can virtually loop in any direction
pickerView selectRow:(row + (INT16_MAX/(2*actual_length))*actual_length) inComponent:component animated:NO];
}
All the above answers and this one are practically the same.This is what livingtech is explaining but with code. And filipe's answer is also right, but if you want an stricter answer just return to the appropiate middle row when the user stops scrolling. Anyway, doing so doesn't offer any practical advantage because the user will get tired sooner than scrolling INT16_MAX/2 times.
回答3:
High level: Specify some finite number of rows in your delegate. Then detect as you get toward the top or bottom of those rows and change the delegate so the row is actually in the middle (or top, or whatever). You would obviously need to change the table's location by using one of the scrolling methods (presumably without animation so it happens without the user knowing).
Make sense? I've never done this, but it should be theoretically possible.
回答4:
Try this component: http://dev.doukasd.com/2011/04/infinite-scrolling-dial-control-for-ios/
It should be as simple as instantiating 2 DialControllers and setting the values you need. The example included is quite similar.
回答5:
Based on the above answers I've created a new component (GWInfinitePickerView) which makes UIPickerView "endless" (of course it has the end but to reach it you have to scroll for a couple of minutes). To change your UIPickerView behaviour you only have to change the class of it. Code and the demo you can find on github (https://github.com/gwikiera/GWInfinitePickerView), or you can simply install it using cocoapods.
来源:https://stackoverflow.com/questions/3618816/uipickerview-infinite-rows