带有 "external" DataSource 和 Swift 中的 Delegate 的 UIPickerView
UIPickerView with "external" DataSource and Delegate in Swift
我的视图中有两个不同的 UIPickerView。当我将数据源和委托设置为它们通过故事板托管的视图时,它们工作得很好,但是当我尝试通过如下所述的代码执行此操作时,它不起作用。
两个选择器都应显示不同的数据(甚至可能代表不同的行为)。因此,我想以编程方式将它们连接到不同的数据源。
我试图创建自己的 class 实现 UIPickerViewDataSource 和 UIPickerViewDelegate 协议,并将 class 的对象连接到我的 PickerView,但它不起作用。运行时抛出异常 terminating with uncaught exception of type NSException
说明:
2015-01-09 17:50:05.333 Pet Stats[4953:244338] -[NSConcreteMapTable numberOfComponentsInPickerView:]: unrecognized selector sent to instance 0x7b4616d0
2015-01-09 17:50:05.338 Pet Stats[4953:244338] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[NSConcreteMapTable numberOfComponentsInPickerView:]: unrecognized selector sent to instance 0x7b4616d0'
我怎样才能让它工作?我错过了什么?这是我的代码:
WeightWheelController.swift
import UIKit
class WeightWheelController: NSObject, UIPickerViewDelegate, UIPickerViewDataSource {
let ElementCount: Int!
init(pickerInterval: Int) {
ElementCount = pickerInterval
}
func numberOfComponentsInPickerView(pickerView: UIPickerView) -> Int {
return 1
}
func pickerView(pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
return ElementCount
}
func pickerView(pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String! {
return String(row + 1)
}
func pickerView(pickerView: UIPickerView!, didSelectRow row: Int, inComponent component: Int)
{
println("External Controller:" + String(row + 1))
}
}
WeightWheelInputViewController.swift
import UIKit
class WeightWheelInputViewController: UIViewController {
@IBOutlet weak var picker1: UIPickerView!
@IBOutlet weak var picker2: UIPickerView!
override func viewDidLoad() {
super.viewDidLoad()
//picker attached to c1 should show number from 1 to 150
let c1 = WeightWheelController(pickerInterval: 150)
//picker attached to c1 should show number from 1 to 10
let c2 = WeightWheelController(pickerInterval: 10)
picker1.dataSource = c1
picker1.delegate = c1
picker2.dataSource = c2
picker2.delegate = c2
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
}
简要更新:
在这个问题中,我发现您可以为不同的选择器视图使用不同的标签。那将是一种选择;然而,我不喜欢它。我宁愿遵循 MVC'ish 方法并将不同的控制器连接到每个选择器。这不可能吗?
delegate
和 datasource
都是无主引用。这意味着 c1
和 c2
将在您超出范围后立即释放。尝试将 c1
和 c2
声明为 class.
的属性
Unowned 引用不会对被引用对象创建强保留(a.k.a。它们不会增加保留计数以防止 ARC 释放被引用对象)。
还要确保从界面构建器中删除了 pickerviews 的委托和数据源属性。
class WeightWheelInputViewController: UIViewController {
@IBOutlet weak var picker1: UIPickerView!
@IBOutlet weak var picker2: UIPickerView!
var c1 : WeightWheelController!
var c2 : WeightWheelController!
override func viewDidLoad() {
super.viewDidLoad()
c1 = WeightWheelController(pickerInterval: 150)
c2 = WeightWheelController(pickerInterval: 10)
picker1.dataSource = c1
picker1.delegate = c1
picker2.dataSource = c2
picker2.delegate = c2
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
}
我的视图中有两个不同的 UIPickerView。当我将数据源和委托设置为它们通过故事板托管的视图时,它们工作得很好,但是当我尝试通过如下所述的代码执行此操作时,它不起作用。
两个选择器都应显示不同的数据(甚至可能代表不同的行为)。因此,我想以编程方式将它们连接到不同的数据源。
我试图创建自己的 class 实现 UIPickerViewDataSource 和 UIPickerViewDelegate 协议,并将 class 的对象连接到我的 PickerView,但它不起作用。运行时抛出异常 terminating with uncaught exception of type NSException
说明:
2015-01-09 17:50:05.333 Pet Stats[4953:244338] -[NSConcreteMapTable numberOfComponentsInPickerView:]: unrecognized selector sent to instance 0x7b4616d0
2015-01-09 17:50:05.338 Pet Stats[4953:244338] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[NSConcreteMapTable numberOfComponentsInPickerView:]: unrecognized selector sent to instance 0x7b4616d0'
我怎样才能让它工作?我错过了什么?这是我的代码:
WeightWheelController.swift
import UIKit
class WeightWheelController: NSObject, UIPickerViewDelegate, UIPickerViewDataSource {
let ElementCount: Int!
init(pickerInterval: Int) {
ElementCount = pickerInterval
}
func numberOfComponentsInPickerView(pickerView: UIPickerView) -> Int {
return 1
}
func pickerView(pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
return ElementCount
}
func pickerView(pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String! {
return String(row + 1)
}
func pickerView(pickerView: UIPickerView!, didSelectRow row: Int, inComponent component: Int)
{
println("External Controller:" + String(row + 1))
}
}
WeightWheelInputViewController.swift
import UIKit
class WeightWheelInputViewController: UIViewController {
@IBOutlet weak var picker1: UIPickerView!
@IBOutlet weak var picker2: UIPickerView!
override func viewDidLoad() {
super.viewDidLoad()
//picker attached to c1 should show number from 1 to 150
let c1 = WeightWheelController(pickerInterval: 150)
//picker attached to c1 should show number from 1 to 10
let c2 = WeightWheelController(pickerInterval: 10)
picker1.dataSource = c1
picker1.delegate = c1
picker2.dataSource = c2
picker2.delegate = c2
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
}
简要更新:
在这个问题中,我发现您可以为不同的选择器视图使用不同的标签。那将是一种选择;然而,我不喜欢它。我宁愿遵循 MVC'ish 方法并将不同的控制器连接到每个选择器。这不可能吗?
delegate
和 datasource
都是无主引用。这意味着 c1
和 c2
将在您超出范围后立即释放。尝试将 c1
和 c2
声明为 class.
Unowned 引用不会对被引用对象创建强保留(a.k.a。它们不会增加保留计数以防止 ARC 释放被引用对象)。
还要确保从界面构建器中删除了 pickerviews 的委托和数据源属性。
class WeightWheelInputViewController: UIViewController {
@IBOutlet weak var picker1: UIPickerView!
@IBOutlet weak var picker2: UIPickerView!
var c1 : WeightWheelController!
var c2 : WeightWheelController!
override func viewDidLoad() {
super.viewDidLoad()
c1 = WeightWheelController(pickerInterval: 150)
c2 = WeightWheelController(pickerInterval: 10)
picker1.dataSource = c1
picker1.delegate = c1
picker2.dataSource = c2
picker2.delegate = c2
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
}