Refresh Core Data in ViewController when Modal View (2nd VC) is Dismissed

I have 2 ViewControllers:

VC1 populates its tableView based on CoreData attribute isPicked, which is bool and show only items with true state. VC2 is a second Modal (not Full Screen) View Controller which allow user to change the state of isPicked attribute: check and uncheck item (make it true or false) and after he pressed save button changes will be saved in CoreData and VC2 will be dismissed. However VC1 doesn't update itself with recent changes comes from VC2.

What I tried:

  • load my array to show in VC1 in viewWillAppear(), but since my VC2 is a modal view and not in full screen this method calls only once
  • tried to implement protocol and delegate, but result is the same - can't reload data (but assume I could done it wrong)

My VC1:

    override func viewDidLoad() {
    super.viewDidLoad()
    let predicate = NSPredicate(format: "isPicked == YES")
    converterArray = load(for: tableView, and: predicate)
}

func load(for tableView: UITableView, with request: NSFetchRequest<Currency> = Currency.fetchRequest(), and predicate: NSPredicate? = nil, sortDescriptor: [NSSortDescriptor] = [NSSortDescriptor(key: "shortName", ascending: true)]) -> [Currency] {
    var array = [Currency]()
    request.predicate = predicate
    request.sortDescriptors = sortDescriptor
    do {
        array = try context.fetch(request)
    } catch {
        print(error)
    }
    DispatchQueue.main.async {
        tableView.reloadData()
    }
    return array
}

My VC2:

    @IBAction func saveButtonPressed(_ sender: UIBarButtonItem) {
    do {
        try context.save()
    } catch {
        print(error)
    }
    dismiss(animated: true)
}

Also please take a look at a short GIF where I show what happens: CLICK

I don't know how after VC2 dismissal automatically update changes in VC1...


I am assuming the data is being saved properly in VC2 and the only issue you have is the right way to reload the data in VC1.

Making VC1 conform to the UIViewControllerTransitioningDelegate and implementing its delegate function animationController(forDismissed dismissed: UIViewController) might solve your problem

Read more here

Try this

// Some function in VC1 which loads VC2
func loadVC2()
{
    let newVC = UIViewController()
    
    // This is important
    newVC.transitioningDelegate = self
    
    present(newVC, animated: true, completion: nil)
}

Then in VC1, implement the function animationController(forDismissed dismissed: UIViewController)

extension VC1: UIViewControllerTransitioningDelegate
{
    // UIViewControllerTransitioningDelegate delegate function auto invoked during modal transitions
    func animationController(forDismissed dismissed: UIViewController) -> UIViewControllerAnimatedTransitioning?
    {
        print("returned back")
        
        // reload your table in VC1 here
        
        /// Returning nil as per guidelines
        return nil
    }
}

Give this a try and see if this solves your problem.