如何在 Swift 中调用 UIPickerView 的 sub-class

How can I invoke a sub-class of UIPickerView inSwift

我有一个 ViewController,它带有一个 UIPickerView 作为单个控件 myPickerView,它是我创建的 class MyPickerView 作为 UIPickerView 的子 class。我通过 myPickerView.viewDidLoad 在 ViewController viewDidLoad 中调用 myPickerView。但是,这不会执行 MyPickerView 的源函数。

我需要说明如何才能完成这项工作。我使用 MyPickerView 的原因是它有很多特殊代码,我不想弄乱主 ViewController。请参阅下面的示例代码:

import UIKit

class ViewController: UIViewController {

@IBOutlet weak var myPickerView: MyPickerView!
override func viewDidLoad() {
    super.viewDidLoad()
    myPickerView.viewDidLoad()
}

override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()
    // Dispose of any resources that can be recreated.
}


}


import UIKit
var gSep = ","
class MyPickerView: UIPickerView , UIPickerViewDataSource,     UIPickerViewDelegate {
var pickerData = [[" "],[" "]]
var category = [""]
var subCategory = [""]
var dictMenuList = [String:String]()

//MARK:- category/subcategory picker


func viewDidLoad() {
    println("MyPickerView: viewDidLoad")

    dictMenuList = ["Medical":"Sub-Cat 1.1,Sub-Cat 1.2,Sub-Cat 1.3,Sub-Cat 1.4,Sub-Cat 1.5,Sub-Cat 1.6,Sub-Cat 1.7",
        "Taxes": "Sub-Cat 2.1,Sub-Cat 2.2,Sub-Cat 2.3,Sub-Cat 2.4",
        "Bills": "Sub-Cat 3.1,Sub-Cat 3.2,Sub-Cat 3.3,Sub-Cat 3.4,Sub-Cat 3.5,Sub-Cat 3.6,Sub-Cat 3.7"]

    println("MyPickerView dictMenuList: \(dictMenuList)")



    self.reloadAllComponents()

    let firstKey = self.loadPickerWithCategory(0)
    self.loadPickerWithSubCategory(firstKey)

}


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

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

func pickerView(pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
    if component == 0 {
        let selectedKey = category[row]
        loadPickerWithSubCategory(selectedKey)
    }
}

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

func pickerView(pickerView: UIPickerView, viewForRow row: Int, forComponent component: Int, reusingView view: UIView!) -> UIView
{
    var pickerLabel = UILabel()
    pickerLabel.textColor = UIColor.blackColor()
    pickerLabel.text = pickerData[component][row]
    pickerLabel.font = UIFont(name: pickerLabel.font.fontName, size: 17)
    pickerLabel.textAlignment = NSTextAlignment.Center
    return pickerLabel
}

func loadPickerWithCategory (row: Int) -> String{
    println("loadPickerWithCategory")
    category = [String](dictMenuList.keys)
    println("MyPickerView: category: \(category)")
    if category.isEmpty {
        return ""
    }
    let n1 = dictMenuList.count
    pickerData[0].removeAll(keepCapacity: true)
    for i in 0 ..< n1
    {
        pickerData[0].append(category[i])
    }
    return category[row]
}

func loadPickerWithSubCategory (key: String) {
    println("MyPickerView: loadPickerWithSubCategory")
    let x = dictMenuList[key]
    subCategory = x!.componentsSeparatedByString(gSep)
    let n1 = subCategory.count
    pickerData[1].removeAll(keepCapacity: true)
    if subCategory.isEmpty {
        return
    }
    for i in 0 ..< n1
    {
        pickerData[1].append(subCategory[i])
    }

    self.reloadAllComponents()
}

}

首先viewDidLoad()UIViewControllerclass的一个方法,在controller的view加载到内存后调用。阅读更多 here。您不能在视图中使用它。

因此您应该在自定义选择器 class 中实现一个 init 方法。我建议覆盖 initWithFrameinitWithCoder 并在那里设置你的组件。

您将像这样初始化您的自定义选择器:

myPickerView = MyPickerView(frame: yourFrame)

方法viewDidLoad是视图控制器方法,不是视图方法。 UIPickerViewUIView 的子类,而不是 UIViewController,因此系统不会调用您的 viewDidLoad 方法。

您需要重写一个或多个初始化方法。

如果您从 Storyboard 或 XIB 加载选择器视图,您可能想要覆盖 initWithCoder。

如果您在代码中创建选择器,您可能想要覆盖 initWithFrame。

我有时创建一个方法 setup,我从 initWithCoder:initWithFrame: 调用它。这样,无论视图对象如何加载,我的设置代码都会被调用。

我依稀记得在 Swift 中读到过有更好的方法来处理这个决斗初始化程序问题,但我不记得它是什么了。 (我还在学习Swift。)

编辑:

我突然想到,在加载视图并设置所有出口后,您可以使用方法 awakeFromNib 进行设置。这大致相当于对视图控制器的 viewDidLoad 调用。我早该想到的。

(awakeFromNib是NSObject的一个方法,如果不知道的话有点难找。)