Swift: извлечение значений из текстовых полей TableView - PullRequest
0 голосов
/ 27 апреля 2020

Я только что попытался извлечь все значения моего текстового поля из моего TableView. Это сработало в 10 из 11 случаев. Я попробовал следующее:

    let journeyIDTextField = tableView.cellForRow(at: NSIndexPath(row: 0, section: 1) as IndexPath) as! InputTableViewCell
    journeyID = journeyIDTextField.cellInputTextfield.text!

Когда я изменяю раздел с 1-10, все работает, раздел 0 приводит к ошибке. Неустранимая ошибка: неожиданно обнаружен ноль при развертывании необязательного значения

Поэтому я попытался проверить, есть ли текстовое поле в IndexPath (0,0).

    print(section.description, indexPath.row, indexPath.section)
    Result: Description 0 0

Так что текстовое поле определенно существует в 0,0. Я понятия не имею, что делать, особенно потому, что он отлично работал на другом ViewController.

Есть идеи?

Best, Тимо

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
}

И это моя ячейка: 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"
    }

}

}

Ответы [ 2 ]

0 голосов
/ 27 апреля 2020

Вы никогда не хотите «получать текст из ячейки». Ячейки используются повторно, поэтому при прокрутке текстового поля, которое было в 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
    }

}

Когда вы запустите его, вы должны получить:

enter image description here

Вы можете вводить текст в полях ... прокручивать вверх и вниз ... и когда При нажатии на кнопку «Проверить данные» вы увидите список свойств перечисления и сохраненные данные из полей.

0 голосов
/ 27 апреля 2020

Я думаю, что одна проблема заключается в том, что вы принудительно разворачиваете journeyIDTextField.cellInputTextfield.text, когда оно равно nil. Еще одна потенциальная проблема, которую я вижу, заключается в том, что текст вашего текстового поля будет стираться при прокрутке из-за повторного использования ячейки. Для правильного использования текстового поля в повторно используемой ячейке см. этот вопрос .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...