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

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了无法将UITextField中的值作为子视图返回到UITableViewCell中的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))
        }
    }
}

但在其他情况下,在下面,问题是UITextFieldUILabelUITableViewCell作为子视图。

我制作了3个swift文件。 2个文件是UITableViewCell子类,1个文件是UITableView类。

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的值之后我可以返回,因为再现了子视图(UITextFieldUILabel)的超级视图的单元格。我很困惑,触摸完成按钮会再次出现细胞。

如何在UITableViewCell中将UITextField中的值返回给UILabel?

谢谢!

答案

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

在那种情况下,我会使用闭包。因此,当您使用TextField实例化单元格时,ViewController告诉Cell按下Done时要执行的操作。为此:

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

希望这可以帮助。

以上是关于无法将UITextField中的值作为子视图返回到UITableViewCell中的UILabel的主要内容,如果未能解决你的问题,请参考以下文章

UITextfield 在 iOS 7 中不能作为 UISearchBar 的子视图?

iPhone SDK - UITableCell 的 UITextField 子视图给出了绘图问题?

将 UITextField 添加到 UITableViewCell

使表格视图中的 UITextField 可见滚动

将逗号添加到数字值作为UITextField中的用户类型

添加 UITextField 作为 UITableViewCell 的子视图在 IOS 6 中工作正常,但在 IOS 7 中它不起作用?