以编程方式创建时从未调用 UIPickerView 委托
UIPickerView delegate never called when created programatically
我正在以编程方式创建 UIPickerView
,然后将其添加到 UIAlertController
。我还创建了一个名为 StringPickerDelegate
的 class,它实现了选择器的委托和数据源协议。
这是我创建 UIPickerView
时的代码
let pickerView = UIPickerView(frame: CGRect(x: 5, y: 20, width: 250, height: 140))
alertController.view.addSubview(pickerView)
let delegate = StringPickerDelegate(items: items) { index, item in
onItemSelected?(item)
}
pickerView.dataSource = delegate
pickerView.delegate = delegate
这是 StringPickerDelegate
class
class StringPickerDelegate: NSObject, UIPickerViewDelegate, UIPickerViewDataSource {
private let items: [String]
private let didSelectItem: ((Int, String) -> Void)
init(items: [String], didSelectItem: @escaping ((Int, String) -> Void)) {
self.items = items
self.didSelectItem = didSelectItem
}
// MARK: UIPickerViewDataSource
func numberOfComponents(in pickerView: UIPickerView) -> Int {
return 1
}
func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
return items.count
}
func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
return items[row]
}
// MARK: UIPickerViewDelegate
func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
didSelectItem(row, items[row])
}
}
我真的无法理解为什么没有调用这些方法。 class 正确地实现了两个委托,我还确保 UIPickerView
被分配并添加为子视图 before 设置委托和数据源。
编辑:我也尝试在 UIAlertController
出现后设置委托以确保所有视图都已完全实例化,但结果是相同的。
UIPickerView.delegate
声明为 weak
(与大多数其他代表一样):
weak var delegate: UIPickerViewDelegate? { get set }
这意味着选择器只持有一个弱引用。在您的代码执行后,没有其他内容会持有对 StringPickerDelegate
的强引用,因此它将被取消初始化!
您需要在 VC 中存储 StringPickerDelegate
的一个实例:
// outside of any method
var pickerDelegate: StringPickerDelegate?
// ...
pickerDelegate = StringPickerDelegate(items: items) { index, item in
onItemSelected?(item)
}
pickerView.dataSource = pickerDelegate!
pickerView.delegate = pickerDelegate!
我正在以编程方式创建 UIPickerView
,然后将其添加到 UIAlertController
。我还创建了一个名为 StringPickerDelegate
的 class,它实现了选择器的委托和数据源协议。
这是我创建 UIPickerView
let pickerView = UIPickerView(frame: CGRect(x: 5, y: 20, width: 250, height: 140))
alertController.view.addSubview(pickerView)
let delegate = StringPickerDelegate(items: items) { index, item in
onItemSelected?(item)
}
pickerView.dataSource = delegate
pickerView.delegate = delegate
这是 StringPickerDelegate
class
class StringPickerDelegate: NSObject, UIPickerViewDelegate, UIPickerViewDataSource {
private let items: [String]
private let didSelectItem: ((Int, String) -> Void)
init(items: [String], didSelectItem: @escaping ((Int, String) -> Void)) {
self.items = items
self.didSelectItem = didSelectItem
}
// MARK: UIPickerViewDataSource
func numberOfComponents(in pickerView: UIPickerView) -> Int {
return 1
}
func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
return items.count
}
func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
return items[row]
}
// MARK: UIPickerViewDelegate
func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
didSelectItem(row, items[row])
}
}
我真的无法理解为什么没有调用这些方法。 class 正确地实现了两个委托,我还确保 UIPickerView
被分配并添加为子视图 before 设置委托和数据源。
编辑:我也尝试在 UIAlertController
出现后设置委托以确保所有视图都已完全实例化,但结果是相同的。
UIPickerView.delegate
声明为 weak
(与大多数其他代表一样):
weak var delegate: UIPickerViewDelegate? { get set }
这意味着选择器只持有一个弱引用。在您的代码执行后,没有其他内容会持有对 StringPickerDelegate
的强引用,因此它将被取消初始化!
您需要在 VC 中存储 StringPickerDelegate
的一个实例:
// outside of any method
var pickerDelegate: StringPickerDelegate?
// ...
pickerDelegate = StringPickerDelegate(items: items) { index, item in
onItemSelected?(item)
}
pickerView.dataSource = pickerDelegate!
pickerView.delegate = pickerDelegate!