UIPickerView – 循环数据
我目前正在使用Swift开发一个应用程序,我使用UIPickerView,请参阅下面的图像。 目前,当用户滚动到最后的数据时,UIPickerView停止,但是我希望它永不停止。 我希望它可以从第一个数据开始,只需在底部滚动即可。 或者在顶部向上滚动。 我希望它能像苹果倒计时一样,只要你想,就可以上下拖动。
我想如何:
目前如何:
这里有四个步骤 – 我们将设置一些常量来保存select器视图数据和一些configuration,然后我们将添加UIPickerViewDataSource
和UIPickerViewDelegate
方法,我们将以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