Swift:将UIPickerView作为循环进行循环

时间:2017-09-13 21:12:47

标签: ios loops uipickerview

"已经回答了类似的问题,但是我的应用程序无效#34;

有什么方法可以让我的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))"
}

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

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

但我在这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)

1 个答案:

答案 0 :(得分:1)

这不是无限循环,但应该可以很好地工作。我们的想法是,您将数据源范围增加了想要添加的任何边距的倍数(我只是将边距随机设置为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)
}