重新加载特定的tableview单元格,并在本地更新数组模型

时间:2019-06-07 12:39:05

标签: ios arrays swift uitableview

我正在开发一个应用程序,该应用程序在表格视图中显示电子邮件列表。每封电子邮件都包含三种状态之一,例如已付款,待处理和争议。我从网络服务响应中获取此数据。如果电子邮件状态已付款,那么我可以在单击“未决”或“争议”按钮时将状态更改为“未决”或“争议”。如果状态已经付款,则用户无法对“付款”按钮执行任何操作。

现在,假设我想通过重新加载该特定单元格并在本地替换该模型的状态来调用Webservice,从而将电子邮件状态从待处理状态更改为已付款。

我该如何做到这一点。

 func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell : HomeTableViewCell = self.tableView.dequeueReusableCell(withIdentifier: cellReuseIdentifier) as! HomeTableViewCell
    if arrayData.count > 0 && arrayData.count > indexPath.row {
    var objemail = self.arrayData.object(at: indexPath.row) as? NewHomeModel
    if objemail?.unread == 1 {
        cell.lblEmailSender.textColor = UIColor.black
        cell.lblEmailDescription.textColor = UIColor.black
    }else{
        cell.lblEmailSender.textColor = UIColor.gray
        cell.lblEmailDescription.textColor = UIColor.gray
    }
    if objemail?.fileStatus == 1 {
        cell.imgAttachment.isHidden = false
    }else{
        cell.imgAttachment.isHidden = true
    }
    cell.lblEmailSender.text = objemail?.from
    cell.lblEmailHeading.text = objemail?.subject
    cell.lblEmailDescription.text = objemail?.body
    var pending = objemail?.pending
    if (pending == 0) {
        cell.btnPending.setBackgroundImage(UIImage(named: "pending_disable_icon"), for: UIControl.State.normal)
        cell.btnPending.addTarget(self, action: #selector(HomeViewController.penddingClick(_:)), for:.touchUpInside )
    }
    else
    {
        cell.btnPending.setBackgroundImage(UIImage(named: "pending_active_icon"), for: UIControl.State.normal)
    }
    if objemail?.dispute == 0 {
        cell.btnDispute.setBackgroundImage(UIImage(named: "dispute_disable_icon"), for: UIControl.State.normal)
        cell.btnDispute.addTarget(self, action: #selector(HomeViewController.disputeClick(_:)), for:.touchUpInside )
    }
    else
    {
        cell.btnDispute.setBackgroundImage(UIImage(named: "dispute_active_icon"), for: UIControl.State.normal)
    }
    if(objemail?.paid == 0)
    {
        cell.btnPaid.setBackgroundImage(UIImage(named: "paid_disable_icon"), for: UIControl.State.normal)
        cell.btnPaid.addTarget(self, action: #selector(HomeViewController.paidClick(_:)), for:.touchUpInside )
    }
    else
    {
        cell.btnPaid.setBackgroundImage(UIImage(named: "paid_active_icon"), for: UIControl.State.normal)

    }
    }
    return cell
}
struct NewHomeModel {
var body: String?
var date : String?
var dispute: Int?
var fileStatus: Int?
var from: String?
var msg_id: String?
var paid: Int?
var pending: Int?
var subject: String?
var thread_id: String?
var unread : Int?
var nextToken : String?

init(jsonData: [String: Any]) {
    body = jsonData["body"] as? String ?? ""
    date = jsonData["date"] as? String ?? ""
    dispute = jsonData["dispute"] as? Int ?? 0
    fileStatus = jsonData["fileStatus"] as? Int ?? 0
    from = jsonData["from"] as? String ?? ""
    msg_id = jsonData["msg_id"] as? String ?? ""
    paid = jsonData["paid"] as? Int ?? 0
    pending = jsonData["pending"] as? Int ?? 0
    subject = jsonData["subject"] as? String ?? ""
    thread_id = jsonData["thread_id"] as? String ?? ""
    unread = jsonData["unread"] as? Int ?? 0
}}

3 个答案:

答案 0 :(得分:1)

您可以使用reloadRows(at:with:)

tableView.reloadRows(at: [indexPathOfTheCellToBeReloaded], with: .automatic)

这是Swift代码。在标记中同时指定Swift和Objective-C时,不确定要用什么。

答案 1 :(得分:1)

您可以在本地重新加载模型数据,并调用tableView.reloadRows(at: IndexPath, with: UITableViewRowAnimation),该调用将使用在模型对象上更新的新数据重新加载单元格。

答案 2 :(得分:1)

假设您的Email模型看起来像

class Email {
    var message: String
    var state: CellState

    init(message: String, state: CellState) {
        self.message = message
        self.state = state
    }
}

其中CellState是一个enum,代表states-cell中的paid, pending, dispute,即

enum CellState {
    case paid, pending, dispute
}

首先,您不得使用cell方法编写tableView(_:cellForRowAt:)的配置代码。 cell's配置必须用cell本身编写,即

class HomeTableViewCell: UITableViewCell {
    var buttonTapHandler: (()->())?
    private var email: Email?

    func configure(with email: Email) {
        self.email = email
        switch email.state {
        case .paid:
            self.backgroundColor = #colorLiteral(red: 0.3411764801, green: 0.6235294342, blue: 0.1686274558, alpha: 1)
        case .pending:
            self.backgroundColor = #colorLiteral(red: 0.9529411793, green: 0.6862745285, blue: 0.1333333403, alpha: 1)
        case .dispute:
            self.backgroundColor = #colorLiteral(red: 0.9254902005, green: 0.2352941185, blue: 0.1019607857, alpha: 1)
        }
    }

    @IBAction func onTapPendingButton(_ sender: UIButton) {
        if self.email?.state != .pending {
            self.email?.state = .pending
            self.buttonTapHandler?()
        }
    }

    @IBAction func onTapDisputeButton(_ sender: UIButton) {
        if self.email?.state != .dispute {
            self.email?.state = .dispute
            self.buttonTapHandler?()
        }
    }

    @IBAction func onTapPaidButton(_ sender: UIButton) {
        if self.email?.state != .paid {
            self.email?.state = .paid
            self.buttonTapHandler?()
        }
    }
}

在上面的代码中,

  1. buttonTapHandler-在点击任意reload之后更改cell cell's时,将处理state的{​​{1}} 。我们将看到如何进一步使用它。

  2. paid/pending/dispute buttons-根据configure(with:)处理UI的{​​{1}}。

  3. cell-更改current state所基于的button tap actions cell's。还调用state以更新button

您的buttonTapHandler看起来像

UI

在上面的代码中,最重要的是我们设置ViewController class VC: UIViewController, UITableViewDataSource { var emails = [Email]() //rest of the code.... func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { return self.emails.count } func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as! HomeTableViewCell let email = self.emails[indexPath.row] cell.configure(with: email) cell.buttonTapHandler = { DispatchQueue.main.async { tableView.reloadRows(at: [indexPath], with: .none) } } return cell } } 的地方,即

cell's

每次在buttonTapHandler的{​​{1}}中点击cell.buttonTapHandler = { DispatchQueue.main.async { tableView.reloadRows(at: [indexPath], with: .none) } } 时都会调用此handler,并且特定的button将是cell