Swift:从 TableView 文本字段中检索值
Posted
技术标签:
【中文标题】Swift:从 TableView 文本字段中检索值【英文标题】:Swift: Retrieving values out of TableView Textfields 【发布时间】:2020-04-27 13:56:14 【问题描述】:我只是试图从我的 TableView 中检索我的所有文本字段值。它适用于 11 个案例中的 10 个。我尝试了以下方法:
let journeyIDTextField = tableView.cellForRow(at: NSIndexPath(row: 0, section: 1) as IndexPath) as! InputTableViewCell
journeyID = journeyIDTextField.cellInputTextfield.text!
当我将部分从 1-10 更改为一切正常时,部分 0 会导致错误。 致命错误:在展开可选值时意外发现 nil
因此我尝试查看 IndexPath (0,0) 处是否有文本字段。
print(section.description, indexPath.row, indexPath.section)
Result: Description 0 0
所以在 0,0 处肯定有一个文本字段。我不知道该怎么做,尤其是因为它在另一个 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
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"
【问题讨论】:
根据您分享的有限信息,很难说。但贴出以下方法:tableView(_:numberOfRowsInSection:)
、numberOfSections(in:)
和tableView(_:cellForRowAt:)
`
更新了,我的错
【参考方案1】:
我认为一个问题是当 journeyIDTextField.cellInputTextfield.text
等于 nil
时,你会强制解包。我看到的另一个潜在问题是,由于单元格重用,当您滚动时,您的文本字段文本将被擦除。要在重复使用的单元格中正确使用文本字段,请参阅this question。
【讨论】:
【参考方案2】:您永远不想“从单元格中获取文本”。单元格被重复使用,因此当您滚动 曾 位于 Section: 0 Row: 0
中的文本字段时,现在可能位于 Section: 10 Row: 0
中。
改为在cellForRowAt
中为您的单元格分配一个“回调闭包”。当用户编辑文本字段时,让您的单元格“回调”到控制器以更新数据源。
这是一个完整的示例,您的代码稍作修改:
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
当你运行它时,你应该得到:
您可以在字段中输入文本...上下滚动...当您点击“检查数据”按钮时,您将看到枚举属性列表和字段中保存的数据。
【讨论】:
以上是关于Swift:从 TableView 文本字段中检索值的主要内容,如果未能解决你的问题,请参考以下文章
如何从 Swift 中嵌入 UITableView 的文本字段中检索数据?
从 tableView 上的核心数据填充数据时如何避免行重复
在 swift 中使用 tableview 和数组过滤器自动完成文本字段