我目前正在開發一個使用Swift的應用程序,我使用UIPickerView,請參閱下面的圖像。目前,當用戶滾動到最後一個數據時,UIPickerView停止,但我希望它永不停止。我希望可以從第一個數據開始,只需在底部滾動即可。或者在頂部向上滾動。我希望它能像蘋果的倒計時一樣,你可以隨時上下拖動。UIPickerView - 循環數據
如何我希望它是:
如何目前,它是:
我目前正在開發一個使用Swift的應用程序,我使用UIPickerView,請參閱下面的圖像。目前,當用戶滾動到最後一個數據時,UIPickerView停止,但我希望它永不停止。我希望可以從第一個數據開始,只需在底部滾動即可。或者在頂部向上滾動。我希望它能像蘋果的倒計時一樣,你可以隨時上下拖動。UIPickerView - 循環數據
如何我希望它是:
如何目前,它是:
會有這裏的四個步驟 - 我們將設置一些常量保持選擇器視圖的數據和那麼我們將添加UIPickerViewDataSource
和UIPickerViewDelegate
方法,我們將以viewDidLoad
初始化結束。
首先,配置:
private let pickerViewData = Array(0...59) // contents will be 0, 1, 2, 3...59, change to whatever you want
private let pickerViewRows = 10_000 // any big number
private let pickerViewMiddle = ((pickerViewRows/pickerViewData.count)/2) * pickerViewData.count
注pickerViewMiddle
不變 - 它計算使它很容易從行偏移得到我們的當前值。到數據源 - 我們只需要提供每行一個標題,但我們會增加一個輔助方法,行號轉換爲值從數組:
extension ViewController : UIPickerViewDataSource {
func valueForRow(row: Int) -> Int {
// the rows repeat every `pickerViewData.count` items
return pickerViewData[row % pickerViewData.count]
}
func rowForValue(value: Int) -> Int? {
if let valueIndex = find(pickerViewData, value) {
return pickerViewMiddle + value
}
return nil
}
func pickerView(pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String! {
return "\(valueForRow(row))"
}
}
最後,我們」 LL設置委託:
extension ViewController : UIPickerViewDelegate {
func numberOfComponentsInPickerView(pickerView: UIPickerView) -> Int {
return 1
}
func pickerView(pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
return pickerViewRows
}
// whenever the picker view comes to rest, we'll jump back to
// the row with the current value that is closest to the middle
func pickerView(pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
let newRow = pickerViewMiddle + (row % pickerViewData.count)
pickerView.selectRow(newRow, inComponent: 0, animated: false)
println("Resetting row to \(newRow)")
}
}
要初始化,請在viewDidLoad
設置委託和數據源,然後移動到正確的行中的選擇器的中間:
self.picker.delegate = self
self.picker.dataSource = self
let initialValue = 0
if let row = rowForValue(initialValue) {
self.picker.selectRow(row, inComponent: 0, animated: false)
}
// or if you just want to start in the middle:
// self.picker.selectRow(pickerViewMiddle, inComponent: 0, animated: false)
這一點已經在這裏找到答案:How do you make an UIPickerView component wrap around?
其基本思想是,您只需創建一個具有足夠大量重複行的選擇器視圖,用戶可能永遠不會到達最後。在上面的答案中,如何創建行數有一個問題,因此我編輯了該部分並在下面提供了其餘的答案。這是Objective-C的,所以你需要將其轉換爲迅速達到你的目的......
@implementation ViewController
NSInteger numberItems;
NSInteger currentValue;
- (void)viewDidLoad {
[super viewDidLoad];
self.pickerView.delegate = self;
numberItems = 60;
currentValue = 0;
[self.pickerView selectRow:(currentValue + (numberItems * 50)) inComponent:0 animated:NO];
[self.view addSubview:self.pickerView];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
}
- (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component {
//return NSIntegerMax; -- this does not work on 64-bit CPUs, pick an arbitrary value that the user will realistically never scroll to like this...
return numberItems * 100;
}
- (NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component {
return [NSString stringWithFormat:@"%ld", row % numberItems];
}
- (void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component {
NSInteger rowValueSelected = row % numberItems;
NSLog(@"row value selected: %ld", (long)rowValueSelected);
}
@end
謝謝!它完美的工作! – ThomasGulli 2014-09-26 20:07:20
正如[本答案](http://stackoverflow.com/a/367436/172218)中提到的那樣,將選取器中的行數設置爲「任何大數字」將VoiceOver擰緊,給出[[大] ]「,這是一個可訪問性問題。任何方式在這個? – 2015-07-08 09:30:45
嗨,內特!你在哪裏聲明你的配置?我在我的課堂上宣佈它,但給我一個錯誤,實例不能在我的課堂上使用。 – 2016-08-01 04:20:37