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

Ios 如何转换UITextField中的数字并将其传递给UITableViewCell中的UILabel?,ios,swift,notifications,Ios,Swift,Notifications,首先,我想像这个货币转换器一样构建我的应用程序 第0行的单元格将有一个UITextLabel作为UITableViewCell的子视图,它从用户处获取一个数字 第2行的单元格将有一个UILabel作为UITableViewCell的子视图,它将显示计算出的数字 第3行的单元格将有一个UILabel作为UITableViewCell的子视图,它将显示计算出的数字。但是这个数字与第2行的数字不同 因此,我创建了3个类,分别为“UITextField”、“UILabel”、“UITableViewC

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

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

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

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

因此,我创建了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子类文件中计算它

或者,我可以在UITableViewController类的cellForRow syntex中通过直接生成UITextLabel实例来实现这一点

但问题是,我无法将计算出的数据传递给UILabel。因为TableViewCell是通过“出列”方法生成的

  • 我无法传递计算数据,因为未生成包含UILabel子视图的单元格
  • 即使生成了单元格,我也无法将“cell”中的数据传递给“cell”,因为“cell”和“cell”都是使用相同的“let cell”通过“dequeue”方法生成的
  • 当然,我无法区分第2行的单元格和第3行的单元格
  • 因此,现在,我无法生成一个函数,在从UITextField接收数据后转换UILabel布局

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

    --------更新---------

    “FroutStableViewCell”子类代码

    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()
    
            }
        }
    
    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)
        }
    }
    
    “AnotherFroutTableViewCell”子类代码

    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()
    
            }
        }
    
    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)
        }
    }
    
    在应用程序中引入模型类,或者至少在视图控制器中引入一些常见的“模型”属性(我不敢这么说,但这是理解和合并模型数据的第一步)。让处理每个控件的viewController代码引用这些相同的模型类,包括基于模型类中的内容进行计算的代码

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


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

    这是一个使用
    通知的完美的示例。您应该向包含标签的每个单元格添加观察者。我猜
    另一个FruitTableViewCell
    是包含标签的单元格,
    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
        }
    
    }
    
    注意:如果您需要计算不同国家/地区的金额,请 标签单元格中需要一些东西来识别国家和地区 当您从中设置标签的数量时,请处理该问题 通知

    现在,当文本字段的值发生变化时,您只需从文本字段单元格posta
    Notification

    编辑:单击“完成”按钮。移除目标并在按钮选择器中实现相同的操作


    谢谢你的回复。我根据您的代码编辑了我的代码,但弹出了一些警告,例如“CellStyle”不是“UITableViewCell”的成员类型,“初始值设定项不会在override init(样式:UITableViewCell.CellStyle,reuseIdentifier:String?)代码中从其超类中重写指定的初始值设定项”。我认为观察者和通知的概念非常强大,但我并不熟悉。因此,我添加了我的'FruitTableViewCell'代码和'AnotherTableViewCell'代码。你能检查和编辑这些代码吗?谢谢@是的,我的语法是Swift 4.2,只需将这些值更改为4.2之前的值。(我想您只需要删除
    。@Hoo我建议您理解我写的内容并更改您的单元格。这并不难,但您可能需要花费一些时间(这是值得的)。坦率地说,您只需将我的代码添加到您的单元格中,而无需更改任何代码。不要要求复制粘贴代码,从长远来看,这对您没有帮助。祝您好运。好的,我知道了!谢谢您的帮助!@Hoo-sure,没问题。:)如果您不了解答案中的某些内容或有关通知的内容,请随时在此处发表评论。