如何将 UIPickerView 选定的行发送到另一个 ViewController

Posted

技术标签:

【中文标题】如何将 UIPickerView 选定的行发送到另一个 ViewController【英文标题】:How do I send UIPickerView selected row to another ViewController 【发布时间】:2020-02-02 17:55:15 【问题描述】:

我想将选定的 UIPickerViews 行发送到另一个视图控制器。我已将 UIPickerView didSelectRow 放在 prepare for segue 函数中。但是,选定的字符串不会转到我的下一个视图控制器。有人可以向我解释我做错了什么吗?我真的很感激。

import UIKit

class LengthViewController: UIViewController, UIPickerViewDelegate, UIPickerViewDataSource, UITextFieldDelegate 


    @IBOutlet weak var lengthTextField: UITextField!
    @IBOutlet weak var lengthPickerView: UIPickerView!
    var startingUnit = ["","Feet","Inches","Nanometer","Millimeter","Meters","Kilometer","Yards","Miles"]
    var finalUnit  = ["","Feet","Inches","Nanometer","Millimeter","Meters","Kilometer","Yards","Miles"]
    var feet = Double()
    var inches = Double()
    var nanometer = Double()
    var millimeter = Double()
    var meters = Double()
    var kilometer = Double()
    var yards = Double()
    var miles = Double()

    override func viewDidLoad() 
        super.viewDidLoad()
        let tap = UITapGestureRecognizer(target: self.view, action: #selector(UIView.endEditing(_:)))
        view.addGestureRecognizer(tap)
        lengthPickerView.delegate = self
        lengthPickerView.dataSource = self
        lengthTextField.delegate = self

    
    func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool 


        guard let oldText = textField.text, let r = Range(range, in: oldText) else 

            return true
        

        let newText = oldText.replacingCharacters(in: r, with: string)
        let isNumeric = newText.isEmpty || (Double(newText) != nil)
        let numberOfDots = newText.components(separatedBy: ".").count - 1

        let numberOfDecimalDigits: Int
        if let dotIndex = newText.firstIndex(of: ".") 
            numberOfDecimalDigits = newText.distance(from: dotIndex, to: newText.endIndex) - 1
         else 
            numberOfDecimalDigits = 0
        

        return isNumeric && numberOfDots <= 1 && numberOfDecimalDigits <= 5
    
    func pickerView(_ pickerView: UIPickerView, viewForRow row: Int, forComponent component: Int, reusing view: UIView?) -> UIView 
        var label = UILabel()
        if let v = view as? UILabel  label = v 
        label.font = UIFont (name: "System", size: 20)
        label.textColor = UIColor.white
        label.text =  startingUnit[row]
        label.text = finalUnit[row]
        label.textAlignment = .center
        return label
    
    func numberOfComponents(in pickerView: UIPickerView) -> Int 
        return 2
    

    func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int 
        if component == 0 
            return startingUnit.count
        else
            return finalUnit.count
        
    
    func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? 
        if component == 0 
            return startingUnit[row]
        else
            return finalUnit[row]
        
    

    override func prepare(for segue: UIStoryboardSegue, sender: Any?) 
        let lengthOutput = segue.destination as! LengthOutputViewController


    func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) 
        if component == 0 
           lengthOutput.startingLength = startingUnit[row] //This is where i try to send to next view controller
        
        if component == 1 
            lengthOutput.endingLength = finalUnit[row] //This is where i try to send to next view controller
        
    

    

    @IBAction func calculatePressed(_ sender: Any) 
        if lengthTextField == nil 
            createAlert(title: "Missing length value", message: "Enter value")
        else
            performSegue(withIdentifier: "lengthOuput", sender: nil)
        
    

    func createAlert (title: String, message: String)
        let alert = UIAlertController(title: title, message: message, preferredStyle: UIAlertController.Style.alert)
        alert.addAction(UIAlertAction(title: "Ok", style: UIAlertAction.Style.default, handler:  (Action) in
            alert.dismiss(animated: true, completion: nil)
        ))
        self.present(alert, animated: true, completion: nil)
    


【问题讨论】:

正如基诺所说,委托函数必须在设置为委托的类的第一级定义。否则,它是看不到的。要在准备中获取 selectedRow,如果您只有一个组件,您还可以调用 lengthPickerView.selectedRow(inComponent: 0)。 【参考方案1】:

pickerview 的 didSelectRow() 应该定义在控制器的顶层。

当它被调用时,将你想要传递给另一个控制器的值存储在一个 ivar 中,然后在 prepare() 中你可以将它分配给另一个控制器的属性。

【讨论】:

【参考方案2】:

我认为您应该做的第一件事是从 prepare 方法中删除您的 didSelectRow 方法,这些方法不应该混合。

要修复您的代码,最好的方法是将当前的起始长度和结束长度存储在始终选择当前值的变量中,因此当按下 calculatePressed 按钮时,您将发送选择的值存储在下一个视图控制器的变量中。

【讨论】:

以上是关于如何将 UIPickerView 选定的行发送到另一个 ViewController的主要内容,如果未能解决你的问题,请参考以下文章

点击完成时如何在uipickerview中获取当前选定的行(具有多个选择器)

如何将选定的行从一个 wpf 数据网格复制到另一个 wpf 数据网格? [关闭]

如何使用 UIPickerView 的选定值作为通知的时间间隔?

从自定义数据源中获取选定的行?

如何在 UIPickerView 中显示所需的行?

如何更改 UIPickerView 中选定行的颜色