无法以编程方式设置UIPickerView dataSource / delegate

时间:2015-08-20 18:21:22

标签: ios swift uipickerview

我有一个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

2 个答案:

答案 0 :(得分:2)

textPickerDelegate位于viewDidLoad的本地。尝试将声明向上移动一级,例如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($0) }, ["a", "b"]]

答案 1 :(得分:1)

您需要将委托添加到您的UIViewController中,如此

class ViewController : UIViewController, UIPickerViewDelegate, UIPickerViewDataSource {

这假设你想要一个标准的UIPickerView