UIPickerView – 循环数据

我目前正在使用Swift开发一个应用程序,我使用UIPickerView,请参阅下面的图像。 目前,当用户滚动到最后的数据时,UIPickerView停止,但是我希望它永不停止。 我希望它可以从第一个数据开始,只需在底部滚动即可。 或者在顶部向上滚动。 我希望它能像苹果倒计时一样,只要你想,就可以上下拖动。

我想如何:

在这里输入图像说明

目前如何:

在这里输入图像说明

这里有四个步骤 – 我们将设置一些常量来保存select器视图数据和一些configuration,然后我们将添加UIPickerViewDataSourceUIPickerViewDelegate方法,我们将以viewDidLoad初始化结束。

一,configuration:

 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))" } } 

最后,我们将设置委托人:

 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设置委托和数据源,然后移动到select器中间的正确行:

 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) 

这已经在这里回答了: 你如何使UIPickerView组件环绕?

基本的想法是,您只需创build一个具有足够多的重复行数的select器视图,用户可能永远不会到达最后。 在上面的答案中,如何创build行数有一个问题,所以我编辑了这一段,并在下面提供了其余的答案。 这是客观的,所以你需要把它转换为你的目的迅速…

 @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