如何在UITextField中转换数字并将其传递给UITableViewCell中的UILabel?

问题描述 投票:2回答:2

首先,我想像这个货币转换器一样构建我的应用程序。

第0行的Cell将有一个UITextLabel作为UITableViewCell的子视图,它从用户获取一个数字。

第2行的Cell将有一个UILabel作为UITableViewCell的子视图,它将显示计算出的数字。

第3行的Cell将有一个UILabel作为UITableViewCell的子视图,它将显示计算出的数字。但是这个数字与第2行的数字不同。

enter image description here

所以我为'UITextField','UILabel','UITableViewController'制作了3个类

这是'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子类文件中计算它。

或者,我可以通过直接创建Text Label实例在UITableViewController类中的cellForRow语法中执行此操作。

但问题是,我无法将计算出的数据传递给UILabel。因为,TableViewCell是由'dequeue'方法制作的。

  1. 我无法传递计算数据,因为没有制作包含UILabel子视图的单元格。
  2. 即使制作了细胞,我也无法将“细胞”中的数据传递给“细胞”,因为“细胞”和“细胞”都是通过'出列'方法使用相同的'let cell'制作的。
  3. 当然,我无法区分Row2的单元格和第3行的单元格。

因此,现在,我无法在从UITextField接收数据后创建转换UILabel布局的函数。

如何在UITextField中转换数字并将其传递给UITextViewCell中的UILabel?

- - - - 更新 - - - - -

'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)
    }
}
ios swift notifications
2个回答
2
投票

这是使用Notifications的完美示例。您应该将观察者添加到包含标签的每个单元格。我猜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
    }

}

注意:如果您需要计算不同国家/地区的金额,则需要标签单元格中的某些内容来标识国家/地区,并在从通知中将金额设置为标签时处理该国家/地区。

现在,当文本字段的值发生变化时,您需要做的就是从文本字段单元格发布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
投票

将模型类引入您的应用程序,或者至少在视图控制器中引入一些常见的“模型”属性(我畏缩地说,但这是理解和合并模型数据的第一步)。让处理每个控件的viewController代码引用这些相同的模型类,包括根据模型类中的内容进行计算的代码。

要触发对表中所有UI的更新,只需调用self.tableView.reloadData()即可。重新加载可见单元格将非常快,标签将从模型数据中重新填充。

(然后有一天从MVC毕业到MVVM并让你的VM类访问模型并进行计算,让你的VC根据VM提供的内容盲目地更新控件。)

© www.soinside.com 2019 - 2024. All rights reserved.