无法以编程方式设置 UIPickerView 数据源/委托

Cannot set UIPickerView dataSource / delegate programmatically

我有一个 UIPickerView,我已将它放在我的故事板上,并在我的控制器中创建了对选取器的引用。在我的控制器中,我想以编程方式设置委托。这是我尝试过的:

class MyViewController: UIViewController {
    @IBOutlet weak var text1: UITextField!
    @IBOutlet weak var text2: UITextField!
    @IBOutlet weak var picker: UIPickerView!

    override func viewDidLoad() {
        super.viewDidLoad()
        let textPickerDelegate = TextPickerdDelegate(text1: text1, text2: text2, picker: picker)

        text1.delegate = textPickerDelegate
        text2.delegate = textPickerDelegate

        picker.delegate = textPickerDelegate
        picker.dataSource = textPickerDelegate
        picker.hidden = true
    }
}

代表的代码如下所示:

class TextPickerDelegate: NSObject, UIPickerViewDelegate, UIPickerViewDataSource, UITextFieldDelegate {
    static let TEXT_1_DATA: Array<Array<String>> = {
        let text1Data: Array<Array<String>> = [[], ["a", "b"]]
        for i in 1...100 {
            var text1 = text1Data[0] as Array<String>
            text1.append(String(i))
        }
        return text1Data
    }()

    static let TEXT_2_DATA: Array<Array<String>> = {
        let text2Data: Array<Array<String>> = [[], ["c", "d"]]
        for i in 1...100 {
            var text2 = text2Data[0] as Array<String>
            text2.append(String(i))
        }
        return text2Data
    }()

    let text1: UITextField
    let text2: UITextField
    let picker: UIPickerView

    var pickerData: Array<Array<String>> = TextPickerDelegate.TEXT_1_DATA

    init(text1: UITextField, text2: UITextField, picker: UIPickerView) {
        self.text1 = text1
        self.text2 = text2
        self.picker = picker
    }

    func numberOfComponentsInPickerView(pickerView: UIPickerView) -> Int {
        return pickerData.count
    }

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

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

    func pickerView(pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
        // Select the row
        picker.hidden = true;
    }

    func textFieldShouldBeginEditing(textField: UITextField) -> Bool {
        if (textField == text1) {
            pickerData = TextPickerDelegate.TEXT_1_DATA
        } else if (textField == text2) {
            pickerData = TextPickerDelegate.TEXT_2_DATA
        }

        picker.hidden = false
        return false
    }
}

当我尝试渲染包含选择器的视图时,我收到以下错误:

2015-08-20 20:19:14.840 MyApp[13642:645025] -[_UIAppearanceCustomizableClassInfo numberOfComponentsInPickerView:]: unrecognized selector sent to instance 0x7fe072d64ba0

您需要像这样将委托添加到您的 UIViewController

class ViewController : UIViewController, UIPickerViewDelegate, UIPickerViewDataSource {

假设您想要一个标准的 UIPickerView

textPickerDelegateviewDidLoad 本地。尝试将声明向上移动一层,例如 IBOutlets。

我认为您的 TEXT_?_DATA 也有潜在问题,请参阅我在其中添加的评论:

static let TEXT_1_DATA: Array<Array<String>> = {
        let text1Data: Array<Array<String>> = [[], ["a", "b"]]
        for i in 1...100 {
            var text1 = text1Data[0] as Array<String> // <-- this creates a copy, not a reference
            text1.append(String(i)) // <-- this appends to the copy, leaving the original intact
        }
        return text1Data
    }()

作为快速替代方法,您可以试试这个:

let text1Data = [(1...100).map { String([=11=]) }, ["a", "b"]]