简体   繁体   中英

Swift: Reading from an UIPickerVIew

I'm trying to read int s from an UIPickerView , I've already done this but it's only a print on an UILabel . this time I need the data so I can put sounds for each number, so I can make a queue announcer (it's a 3-digit UIPickerView and starts from "001" to "999". see I don't know the code to give each component's selected number a sound. (I've already imported the sounds via AVFoundation but I won't paste it here in my code). And as I've mentioned in the comments, Converting isn't my problem. So this question is new. Here's what I have so far:

import UIKit
import AVFoundation

class ViewController: UIViewController, UIPickerViewDataSource, UIPickerViewDelegate {
    //Picker View Settings
    @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)"
    }

    //"Next" Button Setting 
    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))"
    }

    //Announcer Button
    @IBAction func soundPlayed(_ sender: Any) {
        //Don't have any function yet, because of my question.
    }

There is a much better way to do what you are trying to do with this code. Don't work with strings. Work with numbers.

The following code keeps track of the current value as an Int . It's updated as the picker values change. Make use of currentValue in any method that needs to know the current value of the pickers.

The idea is that you do not use views to keep data. Views only show data. Keep the data stored separately.

class ViewController: UIViewController, UIPickerViewDataSource, UIPickerViewDelegate {
    @IBOutlet weak var label: UILabel!
    @IBOutlet weak var pickerView: UIPickerView!

    var currentValue = 0

    func updateCurrentValue() {
        // Use max(0, xxx) since `selectedRow` can return -1 if the component has no selection
        let hundreds = max(0, pickerView.selectedRow(inComponent: 0))
        let tens = max(0, pickerView.selectedRow(inComponent: 1))
        let ones = max(0, pickerView.selectedRow(inComponent: 2))

        currentValue = hundreds * 100 + tens * 10 + ones
    }

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

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

    fun pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
        return 10 // digits 0 - 9
    }

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

        changeLabelText()
    }

    @IBAction func buttonPressed() {
        currentValue = (currentValue + 1) % 1000

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

        changeLabelText()
    }

    fileprivate func changeLabelText() {
        label.text = String(currentValue)
    }

    @IBAction func soundPlayed(_ sender: Any) {
        // Do something with currentValue
    }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM