Swift:使 UIPickerView 作为循环循环

Sha*_*hin 0 loops uipickerview ios

“已经回答了类似的问题,但不适用于我的应用程序”

有什么办法可以让我UIPickerView循环播放吗?我每列都有 0 到 9,但我不希望它以 9 结束。我还有一个 UIButton,它有一个func使数字跳过一个数字的数字,它从 000 到 999 开始,如果我UIPickerView将一个循环我不希望它对其数学顺序进行任何更改或影响这是到目前为止我所拥有的:

class ViewController: UIViewController, UIPickerViewDataSource, UIPickerViewDelegate {

@IBOutlet weak var label: UILabel!
@IBOutlet weak var pickerView: UIPickerView!

let numbers = ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9"]

func numberOfComponents(in pickerView: UIPickerView) -> Int {
    return 3
}

func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
    return numbers[row]
}

func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
    return numbers.count
}

func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {

    let val1 = numbers[pickerView.selectedRow(inComponent: 0)]
    let val2 = numbers[pickerView.selectedRow(inComponent: 1)]
    let val3 = numbers[pickerView.selectedRow(inComponent: 2)]

    label.text = "\(val1) \(val2) \(val3)"
}

fileprivate func num(_ i: Int) -> Int {
    return pickerView.selectedRow(inComponent: i)
}

@IBAction func buttonPressed() {
    let currentNum = num(0) * 100 + num(1) * 10 + num(2)
    let nextNum = currentNum + 1

    pickerView.selectRow(nextNum % 1000 / 100, inComponent: 0, animated: true)
    pickerView.selectRow(nextNum % 100 / 10, inComponent: 1, animated: true)
    pickerView.selectRow(nextNum % 10, inComponent: 2, animated: true)

    changeLabelText()
}

fileprivate func changeLabelText() {
    label.text = "\(num(0)) \(num(1)) \(num(2))"
}
Run Code Online (Sandbox Code Playgroud)

根据已回答的其他问题,我必须编辑我的代码,例如:

class ViewController: UIViewController, UIPickerViewDataSource, UIPickerViewDelegate {

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

func numberOfComponentsInPickerView(pickerView: UIPickerView) -> Int {
    return 3
}

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



@IBOutlet weak var label: UILabel!
@IBOutlet weak var pickerView: UIPickerView!

let numbers = ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9"]

func numberOfComponents(in pickerView: UIPickerView) -> Int {
    return 3
}

func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
    return numbers[row]
}

func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
    return numbers.count
}

func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {

    let val1 = numbers[pickerView.selectedRow(inComponent: 0)]
    let val2 = numbers[pickerView.selectedRow(inComponent: 1)]
    let val3 = numbers[pickerView.selectedRow(inComponent: 2)]

    label.text = "\(val1) \(val2) \(val3)"
}

fileprivate func num(_ i: Int) -> Int {
    return pickerView.selectedRow(inComponent: i)
}

@IBAction func buttonPressed() {
    let currentNum = num(0) * 100 + num(1) * 10 + num(2)
    let nextNum = currentNum + 1

    pickerView.selectRow(nextNum % 1000 / 100, inComponent: 0, animated: true)
    pickerView.selectRow(nextNum % 100 / 10, inComponent: 1, animated: true)
    pickerView.selectRow(nextNum % 10, inComponent: 2, animated: true)

    changeLabelText()
}

fileprivate func changeLabelText() {
    label.text = "\(num(0)) \(num(1)) \(num(2))"
}


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






override func viewDidLoad() {
    super.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)
}
Run Code Online (Sandbox Code Playgroud)

但我在这 6 条不同的线路上遇到了 6 个错误:

 if let valueIndex = find(pickerViewData, value) {
        return pickerViewMiddle + value
//
return "\(valueForRow(row))"
//
 private let pickerViewMiddle = ((pickerViewRows / pickerViewData.count) / 2) * pickerViewData.count

//
self.picker.delegate = self
    self.picker.dataSource = self
    let initialValue = 0
    if let row = rowForValue(initialValue) {
        self.picker.selectRow(row, inComponent: 0, animated: false)
Run Code Online (Sandbox Code Playgroud)

HMH*_*ero 5

这并不是真正的无限循环,但应该工作得很好。这个想法是,您可以将数据源范围增加您想要添加的任何边距的倍数(我只是随机将边距设置为 40),并且当滚动停止时,恢复到数据源范围的中间。此实现将像无限循环一样工作,除非用户滚动 (40 / 2 x 10) 项而不停止滚动。添加了代码来展示这个想法。

let loopingMargin: Int = 40

var data: [String] = ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9"]

var picker: UIPickerView  = UIPickerView()

override func viewDidLoad() {
    super.viewDidLoad()

    picker.delegate = self
    picker.dataSource = self
    view.addSubview(picker)
    picker.selectRow((loopingMargin / 2) * data.count, inComponent: 0, animated: false)
}


// MARK: UIPickerViewDelegate, UIPickerViewDataSource
func numberOfComponents(in pickerView: UIPickerView) -> Int {
    return 1
}

func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
    return loopingMargin * data.count
}

func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
    return data[row % data.count]
}

func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
    let currentIndex = row % data.count
    picker.selectRow((loopingMargin / 2) * data.count + currentIndex, inComponent: 0, animated: false)
}
Run Code Online (Sandbox Code Playgroud)