显示来自 pickerview 的数据
Showing data from pickerview
我为 pickerview 设计了一个带有文本字段的表格视图单元格。我已经在我的表格视图中加载了其中的 2 个单元格。为了显示来自 pickerview 的数据,这是我在 cellForRowAt...
中所做的
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell: sellTableViewCell = tableView.dequeueReusableCell(withIdentifier: "sellProductIdentifier") as! sellTableViewCell
cell.delegate = self
let pickerView = UIPickerView()
pickerView.delegate = self
cell.pickerField.inputView = pickerView
cell.pickerField.text = myData[0]//myData is an array with values from 1-10
myCell = cell //The issue seems to be here.
return cell
}
我给出的选择器视图方法是这样的...
func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
return myData.count
}
func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
return myData[row]
}
func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
myCell.pickerField.text = myData[row]
}
问题是,如果我单击第二个选择器视图,我 select 的值将分配给文本字段。但是当我 select 来自第一个字段的值时,该值显示在第二个字段而不是第一个字段中。
编辑: 这是我在 cellForRowAt
...
中的代码
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell: sellTableViewCell = tableView.dequeueReusableCell(withIdentifier: "sellProductIdentifier") as! sellTableViewCell
cell.delegate = self
let pickerView = MyPickerView()
pickerView.cell = cell
pickerView.delegate = self
cell.qtyPickerField.inputView = pickerView
return cell
}
这是选择器视图方法...
func numberOfComponents(in pickerView: UIPickerView) -> Int {
return 1
}
func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
return myData.count
}
func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
return myData[row]
}
func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
if pickerView is MyPickerView {
if let cell = (pickerView as! MyPickerView).cell {
let indexpath = self.tableview.indexPath(for: cell)
if let index = indexpath {
(pickerView as! MyPickerView).cell?.qtyPickerField?.text = myData[index.row]
}
}
}
}
编辑 2。 pickerview 代码 didSelectRow
func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
if pickerView is MyPickerView {
if let cell = (pickerView as! MyPickerView).cell {
cell.qtyPickerField.text = myData[row]
let indexPath = self.tableview.indexPath(for: cell)
if let index = indexPath {
(pickerView as! MyPickerView).cell?.qtyPickerField?.text = myData[index.row]
}
}
}
}
您需要在自定义单元格中实施选择器视图委托 class sellTableViewCell
您应该在自定义单元格中实现选取器委托,这样您就不必引用单元格并更新该单元格的文本字段中的文本。如果您在单元格中实现了这些委托方法,那么您必须更新该单元格实例的文本字段中的文本。所以在不同的单元格中不会混合文本。同时,您必须为数组中的 indexPath 更新数据模型对象中的此值,以便在滚动时可以保留该值。请参阅我在 link 上的回答以了解如何实施。
问题始于
myCell = cell;
您将始终在此处拥有最新单元格的实例。因此,在委托中分配值将更新最新调用中的 textField。
你可以在 pickerView 委托中做的是(尽管是菜鸟方式 :p)
if let cell = tableView.cellForRow(at: INDEXPATH_OF_RESPECTIVE_ROW) {
"get text field instance and assign value."
}
问题:
正如上面回答中提到的那样
myCell = cell
//问题好像出在这里
是罪魁祸首。因为每次 cellForRowAtIndexPath
完成时,您的 myCell 都会引用最后返回的单元格,而不是负责显示 pickerView
.
的单元格
首先从cellForRowAtIndexPath
中删除myCell = cell
解法:
现在您所要做的就是找出哪个单元格包含负责显示 pickerView 的 textField。
现在可以有多种解决方案。这是一个
第一步:创建PickerView的子类
class MyPickerView : UIPickerView {
weak var cell : MyTableViewCell? = nil
}
在您的代码中使用此 pickerView 而不是 UIPickerView
。
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell: sellTableViewCell = tableView.dequeueReusableCell(withIdentifier: "sellProductIdentifier") as! sellTableViewCell
cell.delegate = self
let pickerView = MyPickerView()
pickerView.cell = cell //pass cells reference
pickerView.delegate = self
cell.pickerField.inputView = pickerView
//other code
}
终于
func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
if pickerView is MyPickerView {
if let cell = (pickerView as! MyPickerView).cell {
cell.textField?.text = myData[row]
let indexPath = self.tableView.indexPath(for: cell)
if let index = indexPath {
//now go ahead and update your data
}
}
}
}
编辑:
此解决方案可以有多种变体。有些人会同意将单元格引用传递给选择器视图是好的,因为单元格无论如何都会持有对选择器的强引用,而选择器只持有对单元格的弱引用。
我个人觉得将 indexPath 作为参数传递给选择器更有意义。最后,当用户选择一些东西时,您将使用传递给选择器的 indexPath 来获取对单元格的引用,并最终更新单元格的文本字段。
O/P:
编辑 2:
由于 OP 仍然很困惑,我决定修改他的编辑 2 并将其添加为答案的一部分
func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
if pickerView is MyPickerView {
if let cell = (pickerView as! MyPickerView).cell {
cell.qtyPickerField.text = myData[row]
let indexPath = self.tableview.indexPath(for: cell)
if let index = indexPath {
//this is only to show you how you can access indexPath
//and in future if you need to update your data source you can use it
//for now ignore this :)
}
}
}
}
应该够好了 :) 希望对你有帮助 :)
我为 pickerview 设计了一个带有文本字段的表格视图单元格。我已经在我的表格视图中加载了其中的 2 个单元格。为了显示来自 pickerview 的数据,这是我在 cellForRowAt...
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell: sellTableViewCell = tableView.dequeueReusableCell(withIdentifier: "sellProductIdentifier") as! sellTableViewCell
cell.delegate = self
let pickerView = UIPickerView()
pickerView.delegate = self
cell.pickerField.inputView = pickerView
cell.pickerField.text = myData[0]//myData is an array with values from 1-10
myCell = cell //The issue seems to be here.
return cell
}
我给出的选择器视图方法是这样的...
func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
return myData.count
}
func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
return myData[row]
}
func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
myCell.pickerField.text = myData[row]
}
问题是,如果我单击第二个选择器视图,我 select 的值将分配给文本字段。但是当我 select 来自第一个字段的值时,该值显示在第二个字段而不是第一个字段中。
编辑: 这是我在 cellForRowAt
...
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell: sellTableViewCell = tableView.dequeueReusableCell(withIdentifier: "sellProductIdentifier") as! sellTableViewCell
cell.delegate = self
let pickerView = MyPickerView()
pickerView.cell = cell
pickerView.delegate = self
cell.qtyPickerField.inputView = pickerView
return cell
}
这是选择器视图方法...
func numberOfComponents(in pickerView: UIPickerView) -> Int {
return 1
}
func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
return myData.count
}
func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
return myData[row]
}
func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
if pickerView is MyPickerView {
if let cell = (pickerView as! MyPickerView).cell {
let indexpath = self.tableview.indexPath(for: cell)
if let index = indexpath {
(pickerView as! MyPickerView).cell?.qtyPickerField?.text = myData[index.row]
}
}
}
}
编辑 2。 pickerview 代码 didSelectRow
func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
if pickerView is MyPickerView {
if let cell = (pickerView as! MyPickerView).cell {
cell.qtyPickerField.text = myData[row]
let indexPath = self.tableview.indexPath(for: cell)
if let index = indexPath {
(pickerView as! MyPickerView).cell?.qtyPickerField?.text = myData[index.row]
}
}
}
}
您需要在自定义单元格中实施选择器视图委托 class sellTableViewCell
您应该在自定义单元格中实现选取器委托,这样您就不必引用单元格并更新该单元格的文本字段中的文本。如果您在单元格中实现了这些委托方法,那么您必须更新该单元格实例的文本字段中的文本。所以在不同的单元格中不会混合文本。同时,您必须为数组中的 indexPath 更新数据模型对象中的此值,以便在滚动时可以保留该值。请参阅我在
问题始于
myCell = cell;
您将始终在此处拥有最新单元格的实例。因此,在委托中分配值将更新最新调用中的 textField。
你可以在 pickerView 委托中做的是(尽管是菜鸟方式 :p)
if let cell = tableView.cellForRow(at: INDEXPATH_OF_RESPECTIVE_ROW) {
"get text field instance and assign value."
}
问题:
正如上面回答中提到的那样
myCell = cell
//问题好像出在这里
是罪魁祸首。因为每次 cellForRowAtIndexPath
完成时,您的 myCell 都会引用最后返回的单元格,而不是负责显示 pickerView
.
首先从cellForRowAtIndexPath
myCell = cell
解法:
现在您所要做的就是找出哪个单元格包含负责显示 pickerView 的 textField。
现在可以有多种解决方案。这是一个
第一步:创建PickerView的子类
class MyPickerView : UIPickerView {
weak var cell : MyTableViewCell? = nil
}
在您的代码中使用此 pickerView 而不是 UIPickerView
。
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell: sellTableViewCell = tableView.dequeueReusableCell(withIdentifier: "sellProductIdentifier") as! sellTableViewCell
cell.delegate = self
let pickerView = MyPickerView()
pickerView.cell = cell //pass cells reference
pickerView.delegate = self
cell.pickerField.inputView = pickerView
//other code
}
终于
func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
if pickerView is MyPickerView {
if let cell = (pickerView as! MyPickerView).cell {
cell.textField?.text = myData[row]
let indexPath = self.tableView.indexPath(for: cell)
if let index = indexPath {
//now go ahead and update your data
}
}
}
}
编辑:
此解决方案可以有多种变体。有些人会同意将单元格引用传递给选择器视图是好的,因为单元格无论如何都会持有对选择器的强引用,而选择器只持有对单元格的弱引用。
我个人觉得将 indexPath 作为参数传递给选择器更有意义。最后,当用户选择一些东西时,您将使用传递给选择器的 indexPath 来获取对单元格的引用,并最终更新单元格的文本字段。
O/P:
编辑 2:
由于 OP 仍然很困惑,我决定修改他的编辑 2 并将其添加为答案的一部分
func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
if pickerView is MyPickerView {
if let cell = (pickerView as! MyPickerView).cell {
cell.qtyPickerField.text = myData[row]
let indexPath = self.tableview.indexPath(for: cell)
if let index = indexPath {
//this is only to show you how you can access indexPath
//and in future if you need to update your data source you can use it
//for now ignore this :)
}
}
}
}
应该够好了 :) 希望对你有帮助 :)