UIPickerView 没有返回用户选择的正确行

UIPickerView not returning the correct row that the user has selected

所以我只是使用 this SO Post 来为我的 ViewController 添加第二个 pickerView。我使用了用户 'LAOMUSIC Arts' 的答案,它实现了使用已接受解决方案中的标签的想法。

这是我的实现:

import UIKit

class ViewController: UIViewController, UIPickerViewDelegate, UIPickerViewDataSource, UITextFieldDelegate{
    var molyRow = ""
    var tungRow = ""

    var molyPickerViewOptions = ["mils", "mm", "in."]
    var tungPickerViewOptions = ["mils", "mm", "in."]



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

    func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
        if (pickerView.tag == 1){
            return molyPickerViewOptions.count
        }else{
            return tungPickerViewOptions.count
        }
    }

    func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
        if (pickerView.tag == 1){
            molyRow = "\(molyPickerViewOptions[row])"
            print("molyRow = ", "\(molyPickerViewOptions[row])")
            return "\(molyPickerViewOptions[row])"

        }else{
            tungRow = "\(tungPickerViewOptions[row])"
            print("tungRow = ", "\(tungPickerViewOptions[row])")
            return "\(tungPickerViewOptions[row])"
        }
    }

如您所见,我让它打印 tungRowmolyRow 及其相应的值。这样,当我是模拟器中的 运行 应用程序时,我可以看到它获得了什么价值。

当我尝试这个时,我偶然发现了一些非常奇怪的东西。当在模拟器中选择它们时,它将正确地 return "mils" 和 "mm",但是如果我从 "mils" 或 "mm" 行中选择 'flick'向下到 "in." 行,由于某种原因它将 return "mils"。我会附上一段视频给你看。

Video

如您所见,选择器似乎在 return "mils" 和 "mm" 大多数 的时间正确,但是基于 如何 我 'flick' 选择器,"in." 不会总是 return 在应该的时候被编辑。

请让我知道我是否可以做些什么来使post更好、更具体等

期待回复。提前致谢!

编辑:在收到尝试 pickerView(_:didSelectRow:inComponent:) 的建议后,我尝试将函数实现到 return,并打印行号。我编辑了 pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) 函数,让它简单地设置标题:

func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
        if (pickerView.tag == 1){
            return "\(molyPickerViewOptions[row])"

        }else{
            return "\(tungPickerViewOptions[row])"
        }
    }

    private func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) -> Int{
        if (pickerView.tag == 1){
            molyRow = row
            print("molyRow = ", "\(row)")
            return row

        }else{
            tungRow = row
            print("tungRow = ", "\(row)")
            return row
        }
    }

请注意,当我尝试实现 pickerView(_:didSelectRow:inComponent:) 函数时,Xcode 警告我:Instance method 'pickerView(_:didSelectRow:inComponent:)' nearly matches optional requirement 'pickerView(_:didSelectRow:inComponent:)' of protocol 'UIPickerViewDelegate' Make 'pickerView(_:didSelectRow:inComponent:)' private to silence this warning

我试过运行但没有实现private。无论哪种方式,它仍然不打印行号。

您似乎正在尝试确定 pickerView(_:titleForRow:forComponent:) 方法中的行选择。每当需要确定要在选择器行中显示的文本时,UIKit 就会调用该方法。

要在选择更改时找出选择了哪一行,您应该查看 pickerView(_:didSelectRow:inComponent:) method of UIPickerViewDelegate

编辑

Swift 没有调用您编写的方法,因为它与委托协议方法的签名不匹配。 pickerView(_:didSelectRow:inComponent:)pickerView(_:didSelectRow:inComponent:) -> Int 不同。这就是为什么您收到有关方法名称几乎(但不完全)匹配的编译器警告的原因。

要让 UIKit 将方法视为它应该调用的方法,您需要删除 Int return。如果方法签名匹配,并且您的 class 被正确分配为选择器的委托(这似乎是因为 titleForRow: 被调用),那么 UIKit 将看到它并调用它。