如何在可重用的 tableView 单元格中更新 UITextfield 中的文本值,每个单元格中的值不同

Posted

技术标签:

【中文标题】如何在可重用的 tableView 单元格中更新 UITextfield 中的文本值,每个单元格中的值不同【英文标题】:How can I update the text values in the UITextfield in a reusable tableView cell, with different values in each cell 【发布时间】:2019-01-04 00:22:34 【问题描述】:

我正在制作一个货币转换器,可在您输入时同时更新货币。货币保存在 tableView 中,单元格是自定义单元格。

我希望能够在一个单元格中输入内容,并查看所有其他单元格都使用转换计算的值进行更新。计算有效,但我不确定如何将数据恢复到正确的单元格中,因为基本上只有一个单元格,因为它是可重复使用的单元格。

这是单元格类,(我只是显示输入以保持清晰。):

class PageCell: UITableViewCell 

let cellCalcInput = UITextField()

func configureCustomCell() 

    contentView.addSubview(cellCalcInput)
    cellCalcInput.translatesAutoresizingMaskIntoConstraints = false
    cellCalcInput.rightAnchor.constraint(equalTo: contentView.rightAnchor, constant: -10).isActive = true
    cellCalcInput.centerYAnchor.constraint(equalTo: contentView.centerYAnchor).isActive = true
    cellCalcInput.font = secondFont?.withSize(18)
    cellCalcInput.textColor = .white
    cellCalcInput.placeholder = "Enter an amount"
    cellCalcInput.keyboardType = .decimalPad
    cellCalcInput.borderStyle = .roundedRect
    cellCalcInput.backgroundColor = .clear

    cellCalcInput.isHidden = true
    self.backgroundColor = .darkGray
    contentView.contentMode = .scaleAspectFit



override init(style: UITableViewCell.CellStyle, reuseIdentifier: String!) 
    super.init(style: style, reuseIdentifier: reuseIdentifier)


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



接下来我创建单元格,我将展示更多内容,以便您了解我如何将每个单元格的数据设置为所选货币。

然后我添加一个 textFieldDidChange 监听器:

   override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell 
    var coinName = String()
    tableView.separatorStyle = .none

    let cell:PageCell = tableView.dequeueReusableCell(withIdentifier: "PageCell") as! PageCell
    cell.configureCustomCell()
    let index = indexPath.row
    let coins = Manager.shared.coins
    let coin = coins[index]
    var coinIndex = Int()
    coinIndex = CGPrices.shared.coinData.index(where:  $0.id == coin )!
    let unit = CGExchange.shared.exchangeData[0].rates[defaultCurrency]!.unit
    coinIndexes.append(coinIndex)

    //Prices from btc Exchange rate.
    let btcPrice = CGPrices.shared.coinData[coinIndex].current_price!
    let dcExchangeRate = CGExchange.shared.exchangeData[0].rates[defaultCurrency]!.value
    let realPrice = (btcPrice*dcExchangeRate)

    setBackground(dataIndex: coinIndex, contentView: cell.contentView)

    coinName = CGPrices.shared.coinData[coinIndex].name

    let imageString = CGPrices.shared.coinData[coinIndex].image 
    cell.theImageView.sd_setImage(with: URL(string: imageString), placeholderImage: UIImage(named: "CryptiXJustX"))

    cell.cellTextLabel.text = coinName
    cell.cellDetailLabel.text = "\(unit)\((round(1000*realPrice)/1000))"

    cell.cellCalcInput.addTarget(self, action: #selector(textFieldDidChange(_:)), for: .editingChanged)

//这里是文本监听器

    return cell


@objc func textFieldDidChange(_ textField: UITextField) 

    var index = Int()
    index = textField.tag

    if textField.text != "" 
    calculations(dataIndex: index, calcInput: textField)
     else 
        print("no text")
    


这是我在输入时进行计算并获得结果的地方,它不完整,但我现在需要以某种方式在每个单元格的 UITextfield 中显示与正确货币相关的这些结果。

    var coinIndexes = [Int]()
var answers = [Double]()
//
var comparitorIndex = 0
func calculations(dataIndex: Int, calcInput: UITextField) 
    let exchangeRate = CGExchange.shared.exchangeData[0].rates[defaultCurrency]!.value
//
    let btcPrice = CGPrices.shared.coinData[dataIndex].current_price!

//
    if answers.count < coinIndexes.count 

        var calculation = ""
        if CGPrices.shared.coinData[dataIndex].id == "bitcoin" 
            calculation = String(Double(calcInput.text!)! / btcPrice)
         else 
        calculation = String(Double(calcInput.text!)! * btcPrice)
        
        let calcAsDouble = Double(calculation)
        let calcFinal = Double(round(1000*calcAsDouble!)/1000)

        var comparitor = coinIndexes[comparitorIndex]
        var comparitorPrice = CGPrices.shared.coinData[comparitor].current_price!

        var comparitorAnswer = (calcFinal/comparitorPrice)
        answers.append(comparitorAnswer)

        comparitorIndex += 1
        print(comparitorAnswer)
        calculations(dataIndex: dataIndex, calcInput: calcInput)
    
    comparitorIndex = 0


这里基本上我根据输入的单元格进行计算,我可以从标签中找出它是哪种货币,然后使用货币的索引我可以检查我的 API 并获取它的名称和值,然后我进行计算以将其他货币与用户输入的值进行比较。计算工作并给出正确的结果,我只是不知道如何将结果发送回正确的单元格。谢谢。

对不起,如果这是非常草率的工作,我对编码还是很陌生。

【问题讨论】:

【参考方案1】:

您可以将结果放入字典类型[Int : Double] 中,其中IntcoinIndexDouble 部分是转换的答案。然后,计算完成后,您可以致电tableView.reloadData.()

您还需要修改 cellForRowAt 以显示转换。

试试这个:

在你的 UIViewController 中声明

var conversions: [Int : Double] = [:]

然后在cellForRowAt:

override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell 
    // your code here
    let conversion = conversions[index]
    // the ?? operator will pass "No Value" string if conversion is nil.
    cell.cellCalcInput.text = String(conversion ?? "No Value")

您需要更新计算函数中的转换

func calculations(dataIndex: Int, calcInput: UITextField) 
    // your code here
    conversions[comparatorIndex] = comparatorAnswer
    // once all conversions are entered
    tableView.reloadData()

我认为你可以改进你的calculations 功能。您可以迭代硬币索引,而不是递归地更新答案。祝你好运!

【讨论】:

这看起来很棒!谢谢你!对于 cellForRowAt 中的部分,我不能这样做,直到我在文本框中输入一些内容或者它发现 nil,但这也可能是因为我已将其更改为 let conversion = conversions[index] cell.cellCalcInput.text = String(Double(conversion!)) 并像原始代码一样强制解包我收到一个错误:“无法使用类型为 '(Double?)' 的参数列表调用类型为 'String' 的初始化程序”有什么想法吗? 我可能只使用一个从 textDidChange 设置为 true 的布尔值,以在执行 cell.cellCalcInput.text = String(conversion) 之前检查它是否为 True 所以只有在 textInput 中肯定有一个值时才会调用它。我会在可能的时候检查这个,当我一切正常时接受! 我更新了答案。您可以使用?? 运算符来检查一个值是否为零,如果是,则传递一个替代值。对于 String(Double(conversion!)) 的情况,请记住 Double(String) 构造函数将返回一个可选项,因为并非所有字符串都可以转换为 double。 谢谢,搞定了。当你说我可以改进我的计算功能时,你能详细说明一下吗?我遇到的最后一个问题是在将所有索引和计算添加到conversions 字典之前处理它们。我正在尝试获取索引和原始价格的字典,然后对该字典中的每个项目执行计算,并将该答案放回转换字典,但我不确定如何格式化。谢谢。 这确实是一个更简洁的解决方案。请记住,您可以使用 for 循环遍历字典中的每个键值对。因此,您的comparator 将成为字典中的键,您将使用dataIndex 来计算费率。这样,您可以将所有计算逻辑放在for 循环中,并取消递归!

以上是关于如何在可重用的 tableView 单元格中更新 UITextfield 中的文本值,每个单元格中的值不同的主要内容,如果未能解决你的问题,请参考以下文章

在可重复使用的表格视图单元格中自动触摸按钮

如何更新 TableView 静态单元格中的数据?

为啥我的 Tableview 重用了一些单元格?

表格单元格中的集合视图。这是重用的错误

在可重复使用的单元格中显示下载进度

重用 uitableview 单元格以及单元格中的子视图