问题描述
我只是试图从TableView中检索所有文本字段值.它为11例病例中的10例起作用.我尝试了以下方法:
I just tried to retrieve all my textfield values out of my TableView. It worked for 10 of 11 cases. I tried the following:
let journeyIDTextField = tableView.cellForRow(at: NSIndexPath(row: 0, section: 1) as IndexPath) as! InputTableViewCell
journeyID = journeyIDTextField.cellInputTextfield.text!
当我将部分从1-10更改为一切正常时,第0部分导致错误.致命错误:展开一个可选值时意外发现nil
When I change the section from 1-10 everything works, section 0 results to an error.Fatal error: Unexpectedly found nil while unwrapping an Optional value
因此,我试图查看IndexPath(0,0)是否存在文本字段.
Therefore I tried to see if there is a textfield at IndexPath (0,0).
print(section.description, indexPath.row, indexPath.section)
Result: Description 0 0
因此,肯定有一个0,0的文本字段.我不知道该怎么办,特别是因为它在另一个ViewController上可以正常工作.
So there is definitely a textfield at 0,0. I have no idea what to do, especially because it worked fine on another ViewController.
有什么想法吗?
最好,蒂莫
func numberOfSections(in tableView: UITableView) -> Int {
return JourneySection.allCases.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: reuseIdentifierInputCell, for: indexPath) as! InputTableViewCell
guard let section = JourneySection(rawValue: indexPath.section) else { return UITableViewCell() }
cell.cellInputTextfield.placeholder = section.description
print(section.description, indexPath.row, indexPath.section)
return cell
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 1
}
这是我的手机:导入UIKit
And this is my cell:import UIKit
class InputTableViewCell: UITableViewCell {
let cellInputTextfield: UITextField = {
let cellInputTextfield = UITextField()
cellInputTextfield.textColor = .black
cellInputTextfield.sizeToFit()
return cellInputTextfield
}()
override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
super.init(style: .default, reuseIdentifier: reuseIdentifier)
cellInputTextfield.frame = CGRect(x: 20, y: 0, width: self.frame.width, height: 60)
cellInputTextfield.font = UIFont.systemFont(ofSize: 15)
self.contentView.addSubview(cellInputTextfield)
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
enum JourneySection:Int, CaseIterable, CustomStringConvertible{
case Description
case ID
case Confirmation
case Destination
case DestinationDate
case DestinationTime
case Arrival
case ArrivalDate
case ArrivalTime
case PriceTotal
case Companions
var description: String {
switch self {
case .Description: return "Description"
case .ID: return "ID f.ex. Flight Number"
case .Confirmation: return "Confirmation No."
case .Destination: return "Destination"
case .DestinationDate: return "Destination Date, like DD-MM-YYYY"
case .DestinationTime: return "Destination Time, like hh-mm"
case .Arrival: return "Arrival"
case .ArrivalDate: return "Arrival Date, like DD-MM-YYYY"
case .ArrivalTime: return "Arrival Time, like hh-mm"
case .PriceTotal: return "Total Price"
case .Companions: return " No. Of Companions"
}
}
}
推荐答案
您永远不想从单元格中获取文本".单元格已被重用,因此当您滚动Section: 0 Row: 0
中的是的文本字段时,现在可能在Section: 10 Row: 0
中.
You never want to "get text from a cell". Cells are reused, so when you scroll the text field that was in Section: 0 Row: 0
may now be in Section: 10 Row: 0
.
相反,请为cellForRowAt
中的单元分配回调关闭".当用户编辑文本字段时,让您的单元格回调"到控制器以更新数据源.
Instead, assign a "callback closure" to your cell in cellForRowAt
. When the user edits the text field, have your cell "call back" to the controller to update the data source.
这是一个完整的示例,您的代码略有修改:
Here is a complete example, with your code slightly modified:
class InputTableViewCell: UITableViewCell {
// callback closure to tell the controller the text field was edited
var callback: ((String) ->())?
let cellInputTextfield: UITextField = {
let cellInputTextfield = UITextField()
cellInputTextfield.textColor = .black
cellInputTextfield.sizeToFit()
return cellInputTextfield
}()
override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
super.init(style: .default, reuseIdentifier: reuseIdentifier)
cellInputTextfield.frame = CGRect(x: 20, y: 0, width: self.frame.width, height: 60)
cellInputTextfield.font = UIFont.systemFont(ofSize: 15)
self.contentView.addSubview(cellInputTextfield)
// add a target func to call when the text field is edited
cellInputTextfield.addTarget(self, action: #selector(textFieldChanged(_:)), for: .editingChanged)
}
@objc func textFieldChanged(_ textField: UITextField) -> Void {
// end the edited text back to the controller
callback?(textField.text ?? "")
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
enum JourneySection:Int, CaseIterable, CustomStringConvertible{
case Description
case ID
case Confirmation
case Destination
case DestinationDate
case DestinationTime
case Arrival
case ArrivalDate
case ArrivalTime
case PriceTotal
case Companions
var description: String {
switch self {
case .Description: return "Description"
case .ID: return "ID f.ex. Flight Number"
case .Confirmation: return "Confirmation No."
case .Destination: return "Destination"
case .DestinationDate: return "Destination Date, like DD-MM-YYYY"
case .DestinationTime: return "Destination Time, like hh-mm"
case .Arrival: return "Arrival"
case .ArrivalDate: return "Arrival Date, like DD-MM-YYYY"
case .ArrivalTime: return "Arrival Time, like hh-mm"
case .PriceTotal: return "Total Price"
case .Companions: return "No. Of Companions"
}
}
}
class JourneyViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {
let testButton: UIButton = {
let v = UIButton()
v.translatesAutoresizingMaskIntoConstraints = false
v.setTitle("Check Data", for: [])
v.setTitleColor(.white, for: [])
v.backgroundColor = .red
return v
}()
let tableView: UITableView = {
let v = UITableView()
v.translatesAutoresizingMaskIntoConstraints = false
return v
}()
let reuseIdentifierInputCell = "journeyCell"
// declare a string data array
var dataStrings: [String] = [String]()
override func viewDidLoad() {
super.viewDidLoad()
// initialize the data array with an empty string for each case
// in actual use, you may have already populated "saved" data
dataStrings = Array(repeating: "", count: JourneySection.allCases.count)
// add the button and table view
view.addSubview(testButton)
view.addSubview(tableView)
// respect safe area
let g = view.safeAreaLayoutGuide
NSLayoutConstraint.activate([
// constrain the button to Top: 20-pts and centered horizontally
testButton.topAnchor.constraint(equalTo: g.topAnchor, constant: 20.0),
testButton.centerXAnchor.constraint(equalTo: g.centerXAnchor),
// constrain the tableview to 8-pts below the button
// Leading / Trailing at 20-pts
// with a height of 240 (so we can see what happens when scrolling)
tableView.topAnchor.constraint(equalTo: testButton.bottomAnchor, constant: 8.0),
tableView.leadingAnchor.constraint(equalTo: g.leadingAnchor, constant: 20.0),
tableView.trailingAnchor.constraint(equalTo: g.trailingAnchor, constant: -20.0),
tableView.heightAnchor.constraint(equalToConstant: 240.0),
])
// register the cell class
tableView.register(InputTableViewCell.self, forCellReuseIdentifier: reuseIdentifierInputCell)
// set dataSource and delegate
tableView.dataSource = self
tableView.delegate = self
// dismiss keyboard when table scrolls
tableView.keyboardDismissMode = .onDrag
testButton.addTarget(self, action: #selector(showData(_:)), for: .touchUpInside)
}
@objc func showData(_ sender: UIButton) -> Void {
for i in 0..<JourneySection.allCases.count {
guard let section = JourneySection(rawValue: i) else {
fatalError("Something wrong with JourneySection")
}
print(section.description, ":", dataStrings[i])
}
}
func numberOfSections(in tableView: UITableView) -> Int {
return JourneySection.allCases.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: reuseIdentifierInputCell, for: indexPath) as! InputTableViewCell
guard let section = JourneySection(rawValue: indexPath.section) else { return UITableViewCell() }
// set placeholder
cell.cellInputTextfield.placeholder = section.description
// set the cell's text field's text
// if this entry in our data source is "", the placeholder will be shown
cell.cellInputTextfield.text = dataStrings[indexPath.section]
// we want the cell to "call us back" when the textfield is edited
cell.callback = { str in
// update our data source
self.dataStrings[indexPath.section] = str
}
return cell
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 1
}
}
运行它,您应该获得:
您可以在字段中输入文本...上下滚动...,然后点击检查数据"按钮,您将看到您的枚举属性列表以及从字段中保存的数据.
You can enter text in the fields... scroll up and down... and when you tap the "Check Data" button you'll see your list of enum properties and the saved data from the fields.
这篇关于Swift:从TableView文本字段中检索值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!