簡體   English   中英

無法將值從 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子類,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
        }
    }
}

FruitTextFieldFruitsTextLabel不像第一個示例代碼那樣在同一個類中。

因此,我無法調用兩個實例並計算ViewController類中的值。 當然,不能返回一個計算值。

而且,我不確定在觸摸完成按鈕以從UITextFieldUILabel獲取值后是否可以返回,因為作為子視圖( UITextFieldUILabel )的超級視圖的單元格被復制。 我很困惑觸摸完成按鈕會再次使單元格出列。

如何將值從 UITextField 返回到 UITableViewCell 中的 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
    }
}

希望這可以幫助。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM