简体   繁体   English

在 Swift 5 中将数据从 UIPickerView 传递到 UIViewController

[英]Passing data from a UIPickerView to a UIViewController in Swift 5

I'm currently trying to build a simple app in Swift 5 that has a main UIViewController :我目前正在尝试在 Swift 5 中构建一个具有主UIViewController的简单应用程序:

class TheList: UIViewController{

    @IBOutlet var tableView: UITableView!

    override func viewDidLoad() {
        super.viewDidLoad()
        tableView.delegate = self
        tableView.dataSource = self
    }
    (...)
}

The UIViewController has an Extension that utilises the UITableViewDataSource and UITableViewDelegate protocols. UIViewController有一个使用UITableViewDataSourceUITableViewDelegate协议的扩展。

extension TheList: UITableViewDelegate, UITableViewDataSource{

(...)

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        switch indexPath.row {
        case 0:
            let cell = tableView.dequeueReusableCell(withIdentifier: "titleViewCell")!
            return cell

(...)

}

It populates the table with certain dynamic UITableViewCells , that are their own, separate classes.它使用某些动态UITableViewCells填充表格,这些动态UITableViewCells是它们自己的独立类。 Here's an example of one:这是一个例子:

class AmtTableViewCell: UITableViewCell{

    @IBOutlet var hoursPickerView: UIPickerView!

    override func awakeFromNib() {
        super.awakeFromNib()
        populate()
        hoursPickerView.delegate = self
        hoursPickerView.dataSource = self
    }

(...)
}

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

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

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


}

As you can see, that UITableViewCell has an outlet of a UIPickerView .如您所见, UITableViewCell有一个UIPickerView的出口。 I would like to somehow pass the data from this class's UIPickerView to my UIViewController , so that I can parse it further there.我想以某种方式将数据从这个类的UIPickerView传递到我的UIViewController ,以便我可以在那里进一步解析它。 I've tried to create a method to do so and then call it in my View Controller, but from I understood I had to instantiate it first, which kills the point, as I would like to get the value from the instance the user sees on their screen.我试图创建一个方法来这样做,然后在我的视图控制器中调用它,但据我所知我必须先实例化它,这会扼杀重点,因为我想从用户看到的实例中获取值在他们的屏幕上。

I have also tried to create an outlet for the Picker in my View Controller and then set up its Delegate and Data Source as the AmtTableViewCell class instead of self but I've learned I can't put that UIPickerView in my UIViewController .我还尝试在我的 View Controller 中为 Picker 创建一个插座,然后将它的 Delegate 和 Data Source 设置为AmtTableViewCell类而不是self但我知道我不能把UIPickerView放在我的UIViewController

Any help is appreciated.任何帮助表示赞赏。

Using closures:使用闭包:

class AmtTableViewCell: UITableViewCell{

    @IBOutlet var hoursPickerView: UIPickerView!
    var selectedValueInPicker: ((String) -> Void)?
    override func awakeFromNib() {
        super.awakeFromNib()
        populate()
        hoursPickerView.delegate = self
        hoursPickerView.dataSource = self
    }

(...)
}
extension AmtTableViewCell: UIPickerViewDelegate, UIPickerViewDataSource{
    func numberOfComponents(in pickerView: UIPickerView) -> Int {
        return 1
    }

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

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

}

extension TheList: UITableViewDelegate, UITableViewDataSource{

(...)

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        switch indexPath.row {
        case 0:
            let cell = tableView.dequeueReusableCell(withIdentifier: "titleViewCell") as? AmtTableViewCell
            cell.selectedValueInPicker = { val in
               //Do what is needed with the Stirng val that is comming from the cell passes in closure
            }
            return cell ?? AmtTableViewCell()

(...)

}

Using Protocol delegate使用协议委托

protocol PickerSelectedValue{
    func didSelectValueInPicker(value: String)
}

class AmtTableViewCell: UITableViewCell{

    @IBOutlet var hoursPickerView: UIPickerView!
    var delegate: PickerSelectedValue?
    override func awakeFromNib() {
        super.awakeFromNib()
        populate()
        hoursPickerView.delegate = self
        hoursPickerView.dataSource = self
    }

(...)
}
extension AmtTableViewCell: UIPickerViewDelegate, UIPickerViewDataSource{
    func numberOfComponents(in pickerView: UIPickerView) -> Int {
        return 1
    }

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

    func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
        return String(pickerData[row])
    }
    func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int){
        delegate?.didSelectValueInPicker(String(pickerData[row]))
    }

}

extension TheList: UITableViewDelegate, UITableViewDataSource,pickerSelectedValue{

(...)

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        switch indexPath.row {
        case 0:
            let cell = tableView.dequeueReusableCell(withIdentifier: "titleViewCell") as? AmtTableViewCell
            cell?.delegate = self
            return cell ?? AmtTableViewCell()

(...)
    func didSelectValueInPicker(value: String){
        print("the selected value in picker was",value)
    }

}

the delegate protocol is little big long in code, but maybe easier to understand is not confortable with closures.委托协议的代码有点长,但可能更容易理解,但不适合使用闭包。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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