从TableView文本字段中检索值

从TableView文本字段中检索值

本文介绍了Swift:从TableView文本字段中检索值的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我只是试图从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文本字段中检索值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-02 06:54