UIPickerView无限行

时间:2010-09-01 13:57:09

标签: iphone uipickerview

如在UIDatePicker中所见,您可以无休止地向上滚动(以及向下滚动)。我也希望实现这一目标,因为我希望人们选择日期,例如:

2010年1月1日 2010年1月2日 ... 2010年12月30日 2010年12月31日 2011年1月1日 ..

所以它可以永远持续下去。我怎么做到这一点?因为我只能在委托中提供特定数量的行。

5 个答案:

答案 0 :(得分:8)

我认为你实际上不能创建UIPickerView循环,但我过去的方式是从numberOfRowsInComponent返回一个非常大的数字,然后计算要返回的行的模数来自viewForRow的适当视图,如下所示:

// 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
}

并在初始化中:

- (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];
}

答案 1 :(得分:4)

我同意上面的大部分(filipe)答案,只有一件事:是的,你可以制作UIPickerView循环:

- (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];
}

所有上述答案和这个答案几乎相同。这就是生活科技正在解释但有代码的。 filipe的答案也是正确的,但是如果你想要一个更严格的答案,只需在用户停止滚动时返回适当的中间行。无论如何,这样做并没有提供任何实际优势,因为用户会比滚动INT16_MAX / 2次更快地感到疲倦。

答案 2 :(得分:2)

高级别:在委托中指定一些有限数量的行。然后检测到这些行的顶部或底部并更改委托,以便行实际位于中间(或顶部,或其他)。您显然需要使用其中一种滚动方法更改表的位置(可能没有动画,因此在用户不知情的情况下发生)。

有意义吗?我从来没有这样做过,但理论上应该可行。

答案 3 :(得分:1)

试试这个组件:http://dev.doukasd.com/2011/04/infinite-scrolling-dial-control-for-ios/

它应该像实例化2个DialControllers并设置所需的值一样简单。包含的例子非常相似。

答案 4 :(得分:1)

基于上面的答案,我创建了一个新组件(GWInfinitePickerView),它使UIPickerView“无穷无尽”(当然它有结束但要达到它你必须滚动几分钟)。要更改UIPickerView行为,您只需更改其类。您可以在github(https://github.com/gwikiera/GWInfinitePickerView)上找到代码和演示,或者您可以使用cocoapods安装它。