[英]Passing data from a UIPickerView to a UIViewController in Swift 5
I'm currently trying to build a simple app in Swift 5 that has a main UIViewController
:我目前正在尝试在 Swift 5 中构建一个具有主
UIViewController
的简单应用程序:
class TheList: UIViewController{
@IBOutlet var tableView: UITableView!
override func viewDidLoad() {
super.viewDidLoad()
tableView.delegate = self
tableView.dataSource = self
}
(...)
}
The UIViewController
has an Extension that utilises the UITableViewDataSource
and UITableViewDelegate
protocols. UIViewController
有一个使用UITableViewDataSource
和UITableViewDelegate
协议的扩展。
extension TheList: UITableViewDelegate, UITableViewDataSource{
(...)
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
switch indexPath.row {
case 0:
let cell = tableView.dequeueReusableCell(withIdentifier: "titleViewCell")!
return cell
(...)
}
It populates the table with certain dynamic UITableViewCells
, that are their own, separate classes.它使用某些动态
UITableViewCells
填充表格,这些动态UITableViewCells
是它们自己的独立类。 Here's an example of one:这是一个例子:
class AmtTableViewCell: UITableViewCell{
@IBOutlet var hoursPickerView: UIPickerView!
override func awakeFromNib() {
super.awakeFromNib()
populate()
hoursPickerView.delegate = self
hoursPickerView.dataSource = self
}
(...)
}
extension AmtTableViewCell: UIPickerViewDelegate, UIPickerViewDataSource{
func numberOfComponents(in pickerView: UIPickerView) -> Int {
return 1
}
func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
return pickerData.count
}
func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
return String(pickerData[row])
}
}
As you can see, that UITableViewCell
has an outlet of a UIPickerView
.如您所见,
UITableViewCell
有一个UIPickerView
的出口。 I would like to somehow pass the data from this class's UIPickerView
to my UIViewController
, so that I can parse it further there.我想以某种方式将数据从这个类的
UIPickerView
传递到我的UIViewController
,以便我可以在那里进一步解析它。 I've tried to create a method to do so and then call it in my View Controller, but from I understood I had to instantiate it first, which kills the point, as I would like to get the value from the instance the user sees on their screen.我试图创建一个方法来这样做,然后在我的视图控制器中调用它,但据我所知我必须先实例化它,这会扼杀重点,因为我想从用户看到的实例中获取值在他们的屏幕上。
I have also tried to create an outlet for the Picker in my View Controller and then set up its Delegate and Data Source as the AmtTableViewCell
class instead of self
but I've learned I can't put that UIPickerView
in my UIViewController
.我还尝试在我的 View Controller 中为 Picker 创建一个插座,然后将它的 Delegate 和 Data Source 设置为
AmtTableViewCell
类而不是self
但我知道我不能把UIPickerView
放在我的UIViewController
。
Any help is appreciated.任何帮助表示赞赏。
Using closures:使用闭包:
class AmtTableViewCell: UITableViewCell{
@IBOutlet var hoursPickerView: UIPickerView!
var selectedValueInPicker: ((String) -> Void)?
override func awakeFromNib() {
super.awakeFromNib()
populate()
hoursPickerView.delegate = self
hoursPickerView.dataSource = self
}
(...)
}
extension AmtTableViewCell: UIPickerViewDelegate, UIPickerViewDataSource{
func numberOfComponents(in pickerView: UIPickerView) -> Int {
return 1
}
func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
return pickerData.count
}
func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
return String(pickerData[row])
}
func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int){
selectedValueInPicker?(String(pickerData[row]))
}
}
extension TheList: UITableViewDelegate, UITableViewDataSource{
(...)
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
switch indexPath.row {
case 0:
let cell = tableView.dequeueReusableCell(withIdentifier: "titleViewCell") as? AmtTableViewCell
cell.selectedValueInPicker = { val in
//Do what is needed with the Stirng val that is comming from the cell passes in closure
}
return cell ?? AmtTableViewCell()
(...)
}
Using Protocol delegate使用协议委托
protocol PickerSelectedValue{
func didSelectValueInPicker(value: String)
}
class AmtTableViewCell: UITableViewCell{
@IBOutlet var hoursPickerView: UIPickerView!
var delegate: PickerSelectedValue?
override func awakeFromNib() {
super.awakeFromNib()
populate()
hoursPickerView.delegate = self
hoursPickerView.dataSource = self
}
(...)
}
extension AmtTableViewCell: UIPickerViewDelegate, UIPickerViewDataSource{
func numberOfComponents(in pickerView: UIPickerView) -> Int {
return 1
}
func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
return pickerData.count
}
func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
return String(pickerData[row])
}
func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int){
delegate?.didSelectValueInPicker(String(pickerData[row]))
}
}
extension TheList: UITableViewDelegate, UITableViewDataSource,pickerSelectedValue{
(...)
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
switch indexPath.row {
case 0:
let cell = tableView.dequeueReusableCell(withIdentifier: "titleViewCell") as? AmtTableViewCell
cell?.delegate = self
return cell ?? AmtTableViewCell()
(...)
func didSelectValueInPicker(value: String){
print("the selected value in picker was",value)
}
}
the delegate protocol is little big long in code, but maybe easier to understand is not confortable with closures.委托协议的代码有点长,但可能更容易理解,但不适合使用闭包。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.