不能 return 从 UITextField 到 UITableViewCell 中的 UILabel 的值作为子视图

Can't return a value from UITextField to UILabel in UITableViewCell as subviews

我做了一个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 swift 个文件。 2 个文件是 UITableViewCell subclasses,1 个文件是 UITableView class.

1. FruitTableViewCell : UITableViewCell subclass

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 subclass

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。表视图控制器:UITableViewController class

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
        }
    }
}

fruitsTextFieldfruitsTextLabel 与第一个示例代码中的 class 不同。

因此,我无法同时调用两个实例并计算 ViewController class 中的值。当然,不能return一个计算值。

而且,我不确定我是否可以在触摸完成按钮后 return 获取从 UITextFieldUILabel 的值,因为单元格是subview(UITextField and UILabel) 被转载。我很困惑,触摸完成按钮会再次使单元格出队。

如何在 UITableViewCell 中 return 从 UITextField 到 UILabel 的值?

谢谢!

如果我理解正确,您想根据另一个单元格中的操作更改一个单元格的某些参数(实际上,这些单元格不同 类 的事实对此并不重要)。 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)
    }
}

您可以使用 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
    }
}

希望这对您有所帮助。