无法将值从UITextField返回到UITableViewCell中的UILabel作为子视图

时间:2018-09-14 03:44:23

标签: ios swift xcode uitextfield uilabel

我做了一个UITextfield来接收用户的数据。

我想将值从UITextField转换为UILabel

我是用简单的UIView完成的,它只有两个对象UITextFieldUILabel

这是有效的代码。

class ViewController: UIViewController, UITextFieldDelegate {

    let inputNumber = UITextField(frame: CGRect(x: 150.0, y: 100.0, width: 200.0, height: 50.0))
    let outputNumber = UILabel(frame: CGRect(x: 150.0, y: 200.0, width: 200.0, height: 50.0))
    let toolBarKeyBoard = UIToolbar()
    let flexibleSpace = UIBarButtonItem(barButtonSystemItem: .flexibleSpace, target: nil, action: nil)
    let doneButton = UIBarButtonItem(barButtonSystemItem: .done, target: nil, action: #selector(donePressed))
    var result : String!

    override func viewDidLoad() {
        super.viewDidLoad()

        calculatePrice()
    }

    func calculatePrice () {

        priceInputLabel.keyboardType = .numberPad
        priceInputLabel.clearButtonMode = .whileEditing

        self.view.addSubview(priceInputLabel)
        toolBarKeyBoard.sizeToFit()
        toolBarKeyBoard.setItems([flexibleSpace, doneButton], animated: false)
        priceInputLabel.inputAccessoryView = toolBarKeyBoard
    }

    @objc func donePressed() {
        view.endEditing(true)
        result = inputNumber.text!
        let convertedNumber = (result as NSString).doubleValue
        if Int(inputNumber.text!) == nil {
            outputNumber.text = String("Nil")
        } else {
            outputNumber.text = String(Int(convertedNumber * 0.85))
        }
    }
}

但是在其他情况下,问题出在下面,是UITextFieldUILabel作为子视图位于UITableViewCell中。

我做了3个快速文件。 UITableViewCell子类是2个文件,UITableView类是1个文件。

1。 FruitTableViewCell:UITableViewCell子类

class FruitTableViewCell: UITableViewCell, UITextFieldDelegate {

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


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

        self.contentView.addSubview(fruitsTextField)

    }

    override func layoutSubviews() {
        super.layoutSubviews()
        fruitsTextField.frame = CGRect(x: 250, y: 7.5, width: 100, height: 30)
        fruitsTextField.textColor = UIColor(red: CGFloat(242/255.0), green: CGFloat(56/255.0), blue: CGFloat(90/255.0), alpha: 1.0)
        fruitsTextField.keyboardType = .numberPad
        fruitsTextField.clearButtonMode = .whileEditing

    toolBarKeyBoard.sizeToFit()

    fruitsTextField.inputAccessoryView = toolBarKeyBoard

    toolBarKeyBoard.setItems([flexibleSpace, doneButton], animated: false)


    }


    @objc func donePressed() {
        fruitTextField.endEditing(true)
    }
}

2。 AnotherFruitTableViewCell:UITableViewCell子类

class AnotherFruitTableViewCell: UITableViewCell {

    var fruitsTextLabel = UILabel()

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

        self.contentView.addSubview(fruitsTextLabel)

    }

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


    override func layoutSubviews() {
        super.layoutSubviews()

        fruitsTextLabel.backgroundColor = UIColor.brown
        fruitsTextLabel.frame = CGRect(x: 250.0, y: 7.5, width: 100.0, height: 30.0)
    }
}

3。 TableViewController: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
        }
    }
}

fruitsTextField fruitsTextLabel 与第一个示例代码不在同一个类中。

因此,我不能同时调用两个实例和计算ViewController类中的值。当然,不能返回计算值。

而且,我不确定在触摸完成按钮以获取从UITextFieldUILabel的值后是否可以返回,因为作为子视图({{1} }和UITextField)被复制。我感到困惑的是,触摸完成按钮会再次使单元出队。

如何在UITableViewCell中将值从UITextField返回到UILabel?

谢谢!

2 个答案:

答案 0 :(得分:0)

如果我正确理解,您想根据另一个单元格中的操作来更改一个单元格的某些参数(实际上,这些单元格属于不同类这一事实对此并不重要)。在这种情况下,ViewController将处于中间状态,因此您需要使单元格与ViewController进行通信。对于两个对象之间的通信,通常使用委托或关闭模式。

在这种情况下,我将使用闭包。因此,当您使用TextField实例化单元格时,ViewController会告诉Cell按下“完成”时该怎么做。要实现这一目标:

  1. var didEntered: ((_ text: String)->())?添加到FruitTableViewCell
  2. didEntered?(fruitsTextField.text ?? "")添加到@objc func donePressed()
  3. 添加(代码基于文本字段值更新第二行-仅作为示例)

    cell.didEntered = {text in
    self.fruitsComponents[1] = text
    self.tableView.reloadRows(at: [IndexPath(row: 1, section: 0)], with: UITableViewRowAnimation.none)}
    

override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell

我在纠正一些错误以使其正常工作的方式上,因此下面是完整的代码。

更新1

import UIKit

class ViewController: UITableViewController, UITextFieldDelegate {

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

    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]
            cell.didEntered = {text in
                self.fruitsLabels = Array(repeating: text, count: 4)
                self.tableView.reloadData()
            }
            return cell
        } else {
            let cell = tableView.dequeueReusableCell(withIdentifier: anotherCellReuseidentifier, for: indexPath) as! AnotherFruitTableViewCell
            cell.textLabel?.text = fruitsComponents[indexPath.row]
            cell.fruitsTextLabel.text = fruitsLabels[indexPath.row]
            return cell
        }


    }
}


class FruitTableViewCell: UITableViewCell, UITextFieldDelegate {

    var fruitsTextField = UITextField()
    let toolBarKeyBoard = UIToolbar()
    let flexibleSpace = UIBarButtonItem(barButtonSystemItem: .flexibleSpace, target: nil, action: nil)
    var result : String!

    var didEntered: ((_ text: String)->())?


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

        self.contentView.addSubview(fruitsTextField)

    }

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

    override func layoutSubviews() {
        super.layoutSubviews()
        fruitsTextField.frame = CGRect(x: 250, y: 7.5, width: 100, height: 30)
        fruitsTextField.backgroundColor = .yellow
        fruitsTextField.textColor = UIColor(red: CGFloat(242/255.0), green: CGFloat(56/255.0), blue: CGFloat(90/255.0), alpha: 1.0)
        fruitsTextField.keyboardType = .numberPad
        fruitsTextField.clearButtonMode = .whileEditing

        toolBarKeyBoard.sizeToFit()

        fruitsTextField.inputAccessoryView = toolBarKeyBoard
        let doneButton = UIBarButtonItem(barButtonSystemItem: .done, target: self, action: #selector(donePressed))
        toolBarKeyBoard.setItems([flexibleSpace, doneButton], animated: false)


    }


    @objc func donePressed() {
        fruitsTextField.endEditing(true)
        didEntered?(fruitsTextField.text ?? "")
    }
}

class AnotherFruitTableViewCell: UITableViewCell {

    var fruitsTextLabel = UILabel()

    override init(style: UITableViewCellStyle, reuseIdentifier: String?) {
        super.init(style: style, reuseIdentifier: reuseIdentifier)
        self.contentView.addSubview(fruitsTextLabel)

    }

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


    override func layoutSubviews() {
        super.layoutSubviews()
        fruitsTextLabel.backgroundColor = UIColor.brown
        fruitsTextLabel.frame = CGRect(x: 250.0, y: 7.5, width: 100.0, height: 30.0)
    }
}

答案 1 :(得分:0)

您可以使用UITextField委托方法在TableViewController中实现这一目标。

在您的TableViewController cellForRowAt方法中:

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] //"I am confused why it is here"
        cell.fruitsTextField.delegate = self
        return cell
    } else {
        let cell = tableView.dequeueReusableCell(withIdentifier: anotherCellReuseidentifier, for: indexPath) as! AnotherFruitTableViewCell
        cell.textLabel?.text = fruitsComponents[indexPath.row]
        return cell
    }
}

现在添加UITextField代理方法:

extension TableViewController : UITextFieldDelegate {
    func textFieldDidEndEditing(_ textField: UITextField) {
        print(textField.text!)

        let cell = self.tableView.cellForRow(at: IndexPath(row: 1, section: 0)) as! AnotherFruitTableViewCell
        cell.textLabel.text = textField.text!
    }

    func textFieldShouldReturn(_ textField: UITextField) -> Bool {
        textField.endEditing(true)
        return true
    }
}

希望这会有所帮助。