2010-09-01 49 views
4

正如在UIDatePicker中可以看到的那樣,您可以無限地向上滾動(以及向下滾動)。我想實現這個太,因爲我希望人們能選擇一個日期,例如:UIPickerView無限行

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

因此它可以永遠持續下去。我怎麼做到這一點?因爲我只能在委託中給出特定數量的行。

回答

2

高級別:在委託中指定一些有限數量的行。然後檢測到這些行的頂部或底部,並更改委託,使行實際上位於中間(或頂部,或其他)。您顯然需要通過使用其中一種滾動方法來更改表格的位置(假設沒有動畫,所以在用戶不知道的情況下發生)。

有意義嗎?我從來沒有這樣做過,但理論上應該是可能的。

7

我不認爲你實際上可以製作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]; 
} 
+0

輝煌,正是我在尋找 – AlBeebe 2013-07-20 19:43:33

+0

Modulo是一個很好的觸摸:)我做了同樣的事情回來編輯它到你的答案,並意識到你已經包括它哈哈! – 2014-04-13 02:41:57

4

我同意上述大部分(菲利普)的答案,只有一兩件事:是的,你可以使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次更快疲勞。

+0

那裏給出了一個問題無窮大問題的有限解決方案。 – Jonny 2013-04-30 03:20:31

+0

嗨,喬尼,好評!但是它有無限的東西嗎?我只是試圖用1000的值顯示一個概念,否則(INT16_MAX /(2 * actual_length))* actual_length)這是很不明確的。 – FranMowinckel 2013-06-24 10:56:45

+0

哇。這是一段很棒的代碼。 – xxtesaxx 2013-08-12 10:59:32

1

基於上述的答案,我創建了一個新的組件(GWInfinitePickerView),它使UIPickerView「無盡」(當然它已經結束,但要達到它,你必須滾動幾分鐘)。要改變你的UIPickerView行爲,你只需要改變它的類。代碼和演示你可以在github上找到(https://github.com/gwikiera/GWInfinitePickerView),或者你可以簡單地使用cocoapods進行安裝。