代码之家  ›  专栏  ›  技术社区  ›  Max

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

  •  0
  • Max  · 技术社区  · 9 年前

    我在故事板上放置了一个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 回复  |  直到 9 年前
        1
  •  2
  •   MirekE    9 年前

    这个 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"]]
    
        2
  •  1
  •   brimstone    9 年前

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

    class ViewController : UIViewController, UIPickerViewDelegate, UIPickerViewDataSource {
    

    这是假设您想要一个标准的UIPickerView