Tableview需要重新加载两次才能从textfield更新数据?

时间:2018-02-15 02:49:20

标签: ios swift uitableview

我对tableView有疑问。

这是我的tableView代码

    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    return tierCount
}

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cellIdentifier = "InterestRateTableViewCell"
    guard let cell = tableView.dequeueReusableCell(withIdentifier: cellIdentifier, for: indexPath) as? InterestRateTableViewCell else {
        fatalError("The dequed cell is not an instance of InterestRateTableViewCell.")
    }

    cell.interestRateTextField.delegate = self
    cell.rowLabel.text = "\(indexPath.row + 1)."

    if let interestText = cell.interestRateTextField.text {
        if let interest = Double(interestText){
            interestRateArray[indexPath.row] = interest
        } else {
            interestRateArray[indexPath.row] = nil
        }
    } else {
        interestRateArray[indexPath.row] = nil
    }
    return cell
}

如您所见,我有cellForRowAt方法从单元格中的文本字段中获取值,并分配给我的数组。 (实际上每个单元格有2个文本字段。)

基本上,我让用户输入并编辑文本字段,直到它们满意为止,然后单击此计算按钮,这将调用计算方法。在计算方法中,我调用" tableView.reloadData()"首先从文本字段中收集数据,然后再进行实际计算。

问题出在我运行应用程序时。我在所有文本字段中输入值然后单击"计算",但它显示错误,如文本字段仍为空。我再次点击,它有效。这就像我不得不重新加载两次才能让事情顺利进行。

任何人都可以帮助我吗?

顺便问一下,请原谅我的英语。我不是来自讲英语的国家。

编辑:在此处按照某人的建议发布计算按钮代码可能很有用。所以,这是计算按钮的代码

     @IBAction func calculateRepayment(_ sender: UIButton) {

    //Reload data to get the lastest interest rate and duration values

    DispatchQueue.main.async {
        self.interestRateTableView.reloadData()
    }

    //Get the loan value from the text field
    if let loanText = loanTextField.text {
        if let loanValue = Double(loanText) {
            loan = loanValue
        } else {
            print("Can not convert loan value to type Double.")
            return
        }
    } else {
        print("Loan value is nil")
        return
    }

    tiers = []
    var index = 0
    var tier: Tier
    for _ in 0..<tierCount {
        if let interestRateValue = interestRateArray[index] {
            if let durationValue = durationArrayInMonth[index] {
                tier = Tier(interestRateInYear: interestRateValue, tierInMonth: durationValue)
                tiers.append(tier)
                index += 1
            } else {
                print("Duration array contain nil")
                return
            }
        } else {
            print("Interest rate array contain nil")
            return
        }
    }
    let calculator = Calculator()
    repayment = calculator.calculateRepayment(tiers: tiers, loan: loan!)
    if let repaymentValue = repayment {
        repaymentLabel.text = "\(repaymentValue)"
        totalRepaymentLabel.text = "\(repaymentValue * Double(termInYear!) * 12)"
    } else {
        repaymentLabel.text = "Error Calculating"
        totalRepaymentLabel.text = ""
    }
}

1 个答案:

答案 0 :(得分:0)

cellForRowAt用于初始创建和配置每个单元格,因此调用此方法时文本字段为空。

UITableView.reloadData()文档:

// Reloads everything from scratch. Redisplays visible rows. Note that this will cause any existing drop placeholder rows to be removed.
open func reloadData()

正如Apple在上面的评论中所说,UITableView.reloadData()将从头开始重新加载所有内容。这包括您的文本字段。

有很多方法可以解决您的问题,但如果没有更多的背景,很难说最好的方法。这是一个非常接近代码当前上下文的示例:

class MyCustomTableViewCell: UITableViewCell {

    @IBOutlet weak var interestRateTextField: UITextField!

    var interestRateChangedHandler: (() -> ()) = nil

    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
        interestRateTextField.addTarget(self, action: #selector(interestRateChanged), for: UIControlEvents.editingChanged)
    }

    @objc
    func interestRateChanged() {
        interestRateChangedHandler?()
    }
}

cellForRowAtIndex

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cellIdentifier = "InterestRateTableViewCell"
    guard let cell = tableView.dequeueReusableCell(withIdentifier: cellIdentifier, for: indexPath) as? InterestRateTableViewCell else {
        fatalError("The dequed cell is not an instance of InterestRateTableViewCell.")
    }

    cell.rowLabel.text = "\(indexPath.row + 1)."
    cell.interestRateChangedHandler = { [weak self] in
        if let interestText = cell.interestRateTextField.text {
            if let interest = Double(interestText){
                self?.interestRateArray[indexPath.row] = interest
            } else {
                self?.interestRateArray[indexPath.row] = nil
            }
        } else {
            self?.interestRateArray[indexPath.row] = nil
        }
    }

    return cell
}