I'm trying to reload table view in Calculation controller, pressing back navigation button on Setup controller (red arrow on screenshot).
Which is the best way to do it? Thanks !
I'm trying to reload table view in Calculation controller, pressing back navigation button on Setup controller (red arrow on screenshot).
Which is the best way to do it? Thanks !
In a navigation controller its's pretty easy. In Swift the most efficient way is a callback closure, it avoids the overhead of protocol/delegate.
In SetupController
declare a callback
property, a closure with no parameter and no return type
var callback : (() -> Void)?
and call it in viewWillDisappear. viewWillDisappear
is allways called when the back button is pressed.
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
callback?()
}
In CalculationController
assign the callback in prepare(for
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
...
let setupController = segue.destination as! SetupController
setupController.callback = {
self.tableView.reloadData()
}
Create delegate with some method for second ViewController. Implement this protocol to first ViewController and when this method is called, reload UITableView
data (in overriden prepare(for:sender:)
set delegate of second ViewController to self
). When second ViewController will disappear, call method on delegate
variable of second ViewController.
Now when you're able to use delegates, you can easily add parameter to delegate's method and pass data from second to first ViewController.
protocol SecondVCDelegate: class { // define delegate protocol
func controllerDismissed()
}
class ViewController: UIViewController {
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "yourIdentifier" {
let destinationVC = segue.destination as! SecondViewController
destinationVC.delegate = self
}
}
}
extension ViewController: SecondVCDelegate {
func controllerDismissed() { // this is called when you call delegate method from second VC
tableView.reloadData()
}
}
class SecondViewController: UIViewController {
weak var delegate: SecondVCDelegate? // delegate variable
override func viewWillDisappear(_ animated: Bool) {
delegate?.controllerDismissed() // call delegate's method when this VC will disappear
}
}
An easy solution is to reload the tableView, when the view is going to appear again.
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
tableView.reloadData()
}
Alternative solutions could be to implement unwindSegue or delegation.
to achieve this you have multiple solutions first of all you have to know what is the best to use by your case,
1- are you passing data back to the CalculationVC
2- do you just need to reload the CalculationVC
each time it appears ?
for the first case you use what called Delegates
in swift
.
for the second case you can use a life-cycle function that is called viewWillAppear()
in the ViewController
.
for the Delegate
case you can find tons of articles online this one recommended for newbies !
and for the second case just use this code.
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
tableView.reloadData()
}
Try this code
protocol VC2Delegate: class {
func viewController(_ myVC2: VC2?, didFinishEditingWithChanges hasChanges: Bool)
}
class VC2 {
private weak var: VC2Delegate? delegate?
weak var: VC2Delegate? delegate?
@IBAction func finishWithChanges() {
delegate.viewController(self, didFinishEditingWithChanges: true)
}
@IBAction func finishWithoutChanges() {
delegate.viewController(self, didFinishEditingWithChanges: false)
}
}
//VC1: implement the VC2Delegate protocol
class VC1: VC2Delegate {
var: Bool _needsReload?
func awakeFromNib() {
super.awakeFromNib()
needsReload = true
}
func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
reloadTableIfNeeded()
}
@IBAction func displayVC2() {
}