Перезагрузка определенной ячейки таблицы с локальным обновлением модели массива - PullRequest
1 голос
/ 07 июня 2019

Я работаю над одним приложением, в котором список адресов электронной почты отображается в виде таблицы.Каждое сообщение содержит один из состояния из три состояния, как платные, в ожидании и данные dispute.This я получаю от ответа WebService.Если состояние электронной почты оплачено, то я могу изменить состояние на ожидающий или оспаривать при нажатии кнопок ожидающих или оспаривать.Если состояние уже оплачено, то пользователь не может выполнять какие-либо действия с оплаченной кнопкой.

Теперь предположим, что я изменяю состояние электронной почты с ожидающего на платное, вызывая 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 ]

1 голос
/ 07 июня 2019

Вы можете перезагрузить данные модели локально и вызвать tableView.reloadRows(at: IndexPath, with: UITableViewRowAnimation), который перезагрузит ячейку с новыми данными, которые вы обновили на объектах вашей модели.

1 голос
/ 07 июня 2019

Давайте предположим, что ваша 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 изменяется после нажатия любой из paid/pending/dispute buttons. Посмотрим, как это можно использовать дальше.

  2. configure(with:) - обрабатывает UI из cell на основе его current state.

  3. 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, т.е.

cell.buttonTapHandler = {
    DispatchQueue.main.async {
        tableView.reloadRows(at: [indexPath], with: .none)
    }
}

Этот handler будет вызываться каждый раз, когда вы нажимаете button в cell в indexPath, и этот конкретный cell будет reloaded.

1 голос
/ 07 июня 2019

Вы можете использовать reloadRows(at:with:):

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

Это код Swift. Не уверен, что вам нужно, так как вы указали Swift и Objective-C в тегах.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...