如何在 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()
是UIViewController
class的一个方法,在controller的view加载到内存后调用。阅读更多 here。您不能在视图中使用它。
因此您应该在自定义选择器 class 中实现一个 init
方法。我建议覆盖 initWithFrame
和 initWithCoder
并在那里设置你的组件。
您将像这样初始化您的自定义选择器:
myPickerView = MyPickerView(frame: yourFrame)
方法viewDidLoad
是视图控制器方法,不是视图方法。 UIPickerView
是 UIView
的子类,而不是 UIViewController
,因此系统不会调用您的 viewDidLoad
方法。
您需要重写一个或多个初始化方法。
如果您从 Storyboard 或 XIB 加载选择器视图,您可能想要覆盖 initWithCoder。
如果您在代码中创建选择器,您可能想要覆盖 initWithFrame。
我有时创建一个方法 setup
,我从 initWithCoder:
和 initWithFrame:
调用它。这样,无论视图对象如何加载,我的设置代码都会被调用。
我依稀记得在 Swift 中读到过有更好的方法来处理这个决斗初始化程序问题,但我不记得它是什么了。 (我还在学习Swift。)
编辑:
我突然想到,在加载视图并设置所有出口后,您可以使用方法 awakeFromNib
进行设置。这大致相当于对视图控制器的 viewDidLoad
调用。我早该想到的。
(awakeFromNib
是NSObject的一个方法,如果不知道的话有点难找。)
我有一个 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()
是UIViewController
class的一个方法,在controller的view加载到内存后调用。阅读更多 here。您不能在视图中使用它。
因此您应该在自定义选择器 class 中实现一个 init
方法。我建议覆盖 initWithFrame
和 initWithCoder
并在那里设置你的组件。
您将像这样初始化您的自定义选择器:
myPickerView = MyPickerView(frame: yourFrame)
方法viewDidLoad
是视图控制器方法,不是视图方法。 UIPickerView
是 UIView
的子类,而不是 UIViewController
,因此系统不会调用您的 viewDidLoad
方法。
您需要重写一个或多个初始化方法。
如果您从 Storyboard 或 XIB 加载选择器视图,您可能想要覆盖 initWithCoder。
如果您在代码中创建选择器,您可能想要覆盖 initWithFrame。
我有时创建一个方法 setup
,我从 initWithCoder:
和 initWithFrame:
调用它。这样,无论视图对象如何加载,我的设置代码都会被调用。
我依稀记得在 Swift 中读到过有更好的方法来处理这个决斗初始化程序问题,但我不记得它是什么了。 (我还在学习Swift。)
编辑:
我突然想到,在加载视图并设置所有出口后,您可以使用方法 awakeFromNib
进行设置。这大致相当于对视图控制器的 viewDidLoad
调用。我早该想到的。
(awakeFromNib
是NSObject的一个方法,如果不知道的话有点难找。)