"已经回答了类似的问题,但是我的应用程序无效#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)
答案 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)
}