UIPickerView无限行

发布于 2024-09-17 05:30:53 字数 208 浏览 6 评论 0原文

正如 UIDatePicker 中所见,您可以无限地向上滚动(也可以向下滚动)。我也想实现这一点,因为我希望人们选择一个日期,例如:

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

所以它可以永远持续下去。我将如何实现这个目标?因为我只能在委托中给出特定数量的行。

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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

似狗非友 2024-09-24 05:30:53

我认为您实际上无法进行 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];
}

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];
}
携君以终年 2024-09-24 05:30:53

我同意上面的大部分(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];
}

所有上面的答案和这个答案实际上是相同的。这就是 Livingtech 正在解释的内容,但是用代码。 filipe 的答案也是正确的,但如果您想要更严格的答案,只需在用户停止滚动时返回到适当的中间行即可。无论如何,这样做不会提供任何实际优势,因为用户会比滚动 INT16_MAX/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.

水晶透心 2024-09-24 05:30:53

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

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

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.

望笑 2024-09-24 05:30:53

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

它应该像实例化 2 个 DialController 并设置您需要的值一样简单。包含的示例非常相似。

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.

莫言歌 2024-09-24 05:30:53

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

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文