1

In my application I have home screen which shows email listing in tableview. After click on any email we redirected to email detail screen where we can update status of email like dispute , paid and pending and also change the status from unread to read email.

After changing status of email on detail screen it is also want to update on email listing in tableview for that specific email when i pop from detail view to email listing.

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
}}
 func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
    if arrayData.count > 0 && arrayData.count > indexPath.row {
        let objemail = arrayData.object(at: indexPath.row) as? NewHomeModel

        let emailDetailVC = EmailDetailViewController()
        emailDetailVC.strThreadId = (objemail?.thread_id)!
        emailDetailVC.strTitle = (objemail?.subject)!
        emailDetailVC.homeModel = objemail
        self.navigationController?.pushViewController(emailDetailVC, animated: true)
    }else{
        print("array empty")
    }
}
Protocol
  • 1,696
  • 13
  • 30
  • Possible duplicate of [Pass data back to previous VC using delegates and update custom cell](https://stackoverflow.com/questions/47843547/pass-data-back-to-previous-vc-using-delegates-and-update-custom-cell) – RajeshKumar R Jun 04 '19 at 05:43
  • What's the point of all of those `?? ""` and `?? 0` ? Either remove those or change all of your properties to not be optional. – rmaddy Jun 04 '19 at 05:45
  • @RajeshKumarR i want to update other values for specific thread id from array and then reload only specific cell on email listing screen – Protocol Jun 04 '19 at 05:55
  • @RahulFate Maybe this one helps you https://stackoverflow.com/a/55860994/10150796 – Nikunj Kumbhani Jun 04 '19 at 05:57
  • @NikunjKumbhani i stuck on updating array for specific key not passing value from B controller to A – Protocol Jun 04 '19 at 05:59
  • @RahulFate So you just need to update the value for the selected index in an array while passing data from B to A and just reload particular that index cell of UITableview. – Nikunj Kumbhani Jun 04 '19 at 06:23
  • It's not clear to me what data you have access to but you say it's not about passing values so does this mean that once you go back to the main VC (with table view) then you have access to the modified email object? – Joakim Danielson Jun 04 '19 at 06:33
  • @RahulFate Can you please share what is your table array type and which value you want to update while comeback from ViewcontorllerB? – Nikunj Kumbhani Jun 04 '19 at 06:48
  • @RahulFate Don't use `NSArray` in swift. use `var arrayData:[NewHomeModel]` – RajeshKumar R Jun 04 '19 at 07:57

2 Answers2

2

detailvieWhen a table view cell is selected perform segue or push EmailDetailViewController. Pass the selected NewHomeModel object to the EmailDetailViewController.

class MainViewController: UITableViewController {
    var arrayData:[NewHomeModel] = [NewHomeModel]()
    //...
    override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        if arrayData.count > 0 && arrayData.count > indexPath.row {
            let objemail = arrayData[indexPath.row]

            let emailDetailVC = EmailDetailViewController()
            emailDetailVC.strThreadId = (objemail.thread_id)!
            emailDetailVC.strTitle = (objemail.subject)!
            emailDetailVC.homeModel = objemail
            emailDetailVC.callBack = { [weak self] objemail in
                self?.arrayData[indexPath.row] = objemail
                self?.tableView.reloadRows(at: [indexPath], with: .automatic)
            }
            self.navigationController?.pushViewController(emailDetailVC, animated: true)
        }else{
            print("array empty")
        }
    }
}

Configure the EmailDetailViewController with the selected NewHomeModel object. Update the values of the object as per your need in this view controller. When going back to MainViewController pass the updated object to the previous view controller using callBack closure.

class EmailDetailViewController: UIViewController {
    var strThreadId:String?
    var strTitle :String?
    var homeModel: NewHomeModel?
    var callBack: ((NewHomeModel)->Void)?
    override func viewDidLoad() {
        super.viewDidLoad()
        homeModel?.unread = 0
        //configure views with selectedModel
    }
    override func viewWillDisappear(_ animated: Bool) {
        super.viewWillDisappear(animated)
        if self.isMovingFromParent, let homeModel = homeModel {
            print("Going back to main view controller")
            callBack?(homeModel)
        }
    }
    func updateStatus() {
        homeModel?.dispute = 1
        homeModel?.paid = 1
        homeModel?.pending = 0
        homeModel?.unread = 0
    }
}

In MainViewController's callBack closure replace the updated object in the data source array and reload the tableview.

RajeshKumar R
  • 15,445
  • 2
  • 38
  • 70
0

You can create Delegate Method to reload data.

protocol NewHomeDelegate: NSObjectProtocol {
func reloadData()
}

after that create delegate variable

weak var delegate: NewHomeDelegate? 

and call it from dental view controller.

Call that delegate function and refresh data

Roshani
  • 21
  • 7