I'm a beginner in Swift. I'm trying to use delegate and protocol to send the data backward from a child view to the root view (in navigation controller)
Here is my code:
//FilterViewController.swift:
protocol FilterDelegate: class {
func finishFilter(query: String);
}
class FilterViewController:BaseViewController,....{
....
weak var delegate : FilterDelegate?
@IBAction func acceptTapped(_ sender: UIButton) {
var querystring = ""
var conditions: [String] = []
//some logic works with conditions
querystring = conditions.joined(separator: "&")
self.delegate?.finishFilter(query: querystring)
self.navigationController?.popViewController(animated: true)
}
}
Here is where I call the delegate from Filter
//HouseListController.swift
class HouseListController: BaseViewController,..{
var filterController = FilterViewController()
//Here is where I push the FilterViewController
@IBAction func filterTapped(_ sender: UIButton) {
self.currentMode = .filter
self.tracking.previousMode = .filter
self.filterController = storyboard?.instantiateViewController(withIdentifier: "FilterView") as! FilterViewController
self.navigationController?.pushViewController(self.filterController, animated: true)
}
override func viewDidLoad() {
self.filterController.delegate = self
}
}
extension HouseListController : FilterDelegate {
func finishFilter(query: String) {
switch self.currentMode{
case .normal:
_ = self.filterHouse(querystring: query , offset: 0, limit: self.tracking.limit).done{ dataHouses in
self.houses.filter = dataHouses
self.houses.defaultHouses = dataHouses
}.done{ _ in
DispatchQueue.main.async {
self.tableView.reloadData()
}
}
case .search:
_ = self.filterHouse(searchKey: self.tracking.search.searchKey, querystring: query, offset: 0, limit: self.tracking.limit).done{ dataHouses in
self.houses.filter = dataHouses
self.houses.defaultHouses = dataHouses
}.done{ _ in
DispatchQueue.main.async {
self.tableView.reloadData()
}
}
default:
_ = self.filterHouse(querystring: query , offset: 0, limit: self.tracking.limit).done{ dataHouses in
self.houses.filter = dataHouses
self.houses.defaultHouses = dataHouses
}.done{ _ in
DispatchQueue.main.async {
self.tableView.reloadData()
}
}
}
self.currentMode = .filter
}
}
The delegate is not calling to my finishFilter function. Instead, when I pop the view in FilterController, it go straight to viewWillAppear in HouseListController and just stuck there without any calling to the delegate.
Am I missing something?
The code you show in filterTapped
is the problem. You create a new instance of FilterViewController
from the storyboard but you never set that instance's delegate
property.
I would get rid of your filterController
property. Get rid of the line in viewDidLoad
that sets its delegate
. You never used that code so you have no need for it.
Then update filterTapped
:
@IBAction func filterTapped(_ sender: UIButton) {
self.currentMode = .filter
self.tracking.previousMode = .filter
let filterController = storyboard?.instantiateViewController(withIdentifier: "FilterView") as! FilterViewController // Update this line
filterController.delegate = self // Add this line
self.navigationController?.pushViewController(self.filterController, animated: true)
}