Как преобразовать число в UITextField и передать его UILabel в UITableViewCell? - PullRequest
0 голосов
/ 15 сентября 2018

Сначала я хочу создать свое приложение, как этот конвертер денег.

Ячейка для строки 0 будет иметь UITextLabel в качестве подпредставления UITableViewCell, которое получает число от пользователей.

Ячейка для строки 2 будет иметь UILabel в качестве подпредставления UITableViewCell, в котором будет показано рассчитанное число.

Ячейка для строки 3 будет иметь UILabel в качестве подпредставления UITableViewCell, в котором будет показано рассчитанное число. Но это число будет отличаться от числа в строке 2.

enter image description here

Итак, я сделал 3 класса для UITextField, UILabel, UITableViewController

Вот код класса 'UITableViewController'.

class TableViewController: UITableViewController, UITextFieldDelegate {

    let fruitsComponents: [String] = ["Apple", "Banana", "Grape", "Pear"]

    let cellReuseidentifier = "cell"
    let anotherCellReuseidentifier = "anotherCell"

    override func viewDidLoad() {
        super.viewDidLoad()

        tableView.register(FruitTableViewCell.self, forCellReuseIdentifier: cellReuseidentifier)
        tableView.register(AnotherFruitTableViewCell.self, forCellReuseIdentifier: anotherCellReuseidentifier)  
    }

    override func numberOfSections(in tableView: UITableView) -> Int {      
        return 1
    }

        override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {        
        return fruitsComponents.count
    }

    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        if indexPath.row == 0 {
            let cell = tableView.dequeueReusableCell(withIdentifier: cellReuseidentifier, for: indexPath) as! FruitTableViewCell
            cell.textLabel?.text = fruitsComponents[indexPath.row]
            return cell
        } else {
            let cell = tableView.dequeueReusableCell(withIdentifier: anotherCellReuseidentifier, for: indexPath) as! AnotherFruitTableViewCell
            cell.textLabel?.text = fruitsComponents[indexPath.row]
            return cell
        }
    }
}

Я могу получить число из UITextField и вычислить его в файле подкласса UITextLabel.

Или я могу сделать это в синтаксисе cellForRow в классе UITableViewController, непосредственно создав экземпляр UITextLabel.

Но проблема в том, что я не могу передать рассчитанные данные в UILabel. Потому что TableViewCell был создан методом dequeue.

  1. Я не могу передать вычисленные данные, потому что ячейки, содержащие подпредставление UILabel, не были созданы.
  2. Даже если ячейки сделаны, я не могу передать данные из «ячейки» в «ячейку», потому что и «ячейка», и «ячейка» были созданы методом «dequeue» с использованием одной и той же «let cell».
  3. Конечно, я не могу дифференцировать ячейку в строке 2 и клетку в строке 3.

Из-за этого теперь я не могу создать функцию, которая преобразует макет UILabel после получения данных из UITextField.

Как преобразовать число в UITextField и передать его UILabel в UITextViewCell?

-------- Обновления ---------

Код подкласса 'FruitsTableViewCell'

class FruitTableViewCell: UITableViewCell, UITextFieldDelegate {

    var numberTextField = UITextField()
    let toolBarKeyBoard = UIToolbar()
    let flexibleSpace = UIBarButtonItem(barButtonSystemItem: .flexibleSpace, target: nil, action: nil)
    lazy var doneButton = UIBarButtonItem(barButtonSystemItem: .done, target: self, action: #selector(donePressed))
    var result : String!

    override init(style: UITableViewCellStyle, reuseIdentifier: String?) {
        super.init(style: style, reuseIdentifier: reuseIdentifier)
        numberTextField.addTarget(self, action: #selector(valueChanged(_:)), for: .valueChanged)
        self.contentView.addSubview(numberTextField)

    }
    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    override func layoutSubviews() {
        super.layoutSubviews()
        numberTextField.frame = CGRect(x: 250, y: 7.5, width: 100, height: 30)
        numberTextField.keyboardType = .numberPad
        toolBarKeyBoard.sizeToFit()
        numberTextField.inputAccessoryView = toolBarKeyBoard
        toolBarKeyBoard.setItems([flexibleSpace, doneButton], animated: false)
    }

    @objc func valueChanged(_ textField: UITextField) {
            var dataDict: [String: Double] = [:]
            dataDict["amount"] = Double(numberTextField.text!) ?? 0
            NotificationCenter.default.post(name: Notification.Name(rawValue: "AmountChanged"), object: nil, userInfo: dataDict)
    }    

    @objc func donePressed() {
        numberTextField.resignFirstResponder()

        }
    }

Код подкласса AnotherFruitTableViewCell

class AnotherFruitTableViewCell: UITableViewCell {


    var outputTextLabel = UILabel()


    override init(style: UITableViewCellStyle, reuseIdentifier: String?) {
        super.init(style: style, reuseIdentifier: reuseIdentifier)
        NotificationCenter.default.addObserver(self, selector: #selector(handleNewAmount(_:)), name: Notification.Name("AmountChanged"), object: nil)
        self.contentView.addSubview(outputTextLabel)

    }

    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }


    override func layoutSubviews() {
        super.layoutSubviews()

        outputTextLabel.frame = CGRect(x: 250.0, y: 7.5, width: 100.0, height: 30.0)
    }

    @objc func handleNewAmount(_ notification: Notification) {
        guard let userInfo = notification.userInfo, let amount = userInfo["amount"] as? Double else {
            return
        }
        let finalAmount = amount * 0.05
        outputTextLabel.text = String(finalAmount)
    }
}

Ответы [ 2 ]

0 голосов
/ 15 сентября 2018

Это идеальный пример использования Notification с.Вы должны добавить наблюдателей в каждую ячейку, которая содержит метку.Я предполагаю, что AnotherFruitTableViewCell - это ячейка, которая содержит метку, а FruitTableViewCell - это ячейка, которая содержит текстовое поле.

class AnotherFruitTableViewCell: UITableViewCell {

    // Initialization of label, country and other code

    override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
        super.init(style: style, reuseIdentifier: reuseIdentifier)

        NotificationCenter.default.addObserver(self, selector: #selector(handleNewAmount(_:)), name: Notification.Name("AmountChanged"), object: nil)
    }

    @objc func handleNewAmount(_ notification: Notification) {
        guard let userInfo = notification.userInfo, let amount = userInfo["amount"] as? Float else {
            return
        }
        let finalAmount = //Some formula
        //Make the necessary changes to amount based on the country
        label.text = finalAmount
    }

}

Примечание: если вам нужно рассчитать сумму для разных странвам нужно что-то в ячейке метки, чтобы идентифицировать страну и обрабатывать это, когда вы устанавливаете сумму для метки из уведомления.

Теперь все, что вам нужно сделать, это post a Notification из ячейки текстового поля, когда значение текстового поля изменяется .

class FruitTableViewCell: UITableViewCell, UITextFieldDelegate {

    // Initialization of text field and other code

    override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
        super.init(style: style, reuseIdentifier: reuseIdentifier)

        textField.addTarget(self, action: #selector(valueChanged(_:)), for: .editingChanged)

    }

    @objc func valueChanged(_ textField: UITextField) {
        var amount: [String: Float] = [:]
        amountDict["amount"] = Int(textField.text!) ?? 0
        NotificationCenter.default.post(name: Notification.Name(rawValue: "AmountChanged"), object: nil, userInfo: amountDict)
    }

}

Редактировать: Для завершения нажатия кнопки.Удалить цель и реализовать то же самое в вашей кнопке селектор .

@objc func donePressed() {
    numberTextField.resignFirstResponder()

    var amount: [String: Float] = [:]
    amountDict["amount"] = Int(numberTextField.text!) ?? 0
    NotificationCenter.default.post(name: Notification.Name(rawValue: "AmountChanged"), object: nil, userInfo: amountDict)
}
0 голосов
/ 15 сентября 2018

Представьте класс (ы) модели в ваше приложение или, по крайней мере, некоторые общие свойства "модели" в вашем контроллере представления (я смущаюсь, говоря это, но это первый шаг к пониманию и включению данных модели). Имейте код viewController, который обрабатывает каждый элемент управления, ссылающийся на те же самые классы модели, включая код для выполнения вычислений, основанных на том, что находится в классах модели.

Чтобы вызвать обновление для всего пользовательского интерфейса в таблице, просто вызовите self.tableView.reloadData (). Перезагрузка видимых ячеек будет достаточно быстрой, и метки будут заполняться данными модели.

(Затем когда-нибудь перейдите от MVC к MVVM, и ваш класс виртуальных машин получит доступ к моделям и выполнит вычисления, позволяя вашему виртуальному каналу просто слепо обновлять элементы управления в соответствии с тем, что ему предоставляет виртуальная машина.)

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