I am developing an application with swift 3.0. Where what I want to do is, from the "MainMapVC" class, which is the view where you have a map with a date slider (see the attached image). I want to move the slider and send that slider position (1,2 or 3) to LeftSideViewController which is the side view (the legend) updating the content depending on the selected date.
View of MainMapVC:
View of MainMapVC with Legend:
Well, and I've come to the point where I have to pass a value between the two view controllers. But problem is that I get the error "fatal error: unexpectedly found nil while unwrapping an optional value". Basically I have a "nil" delegate.
But do not find where the error is, because the definition of the delegate is like "var delegate: MainMapVCDelegate!" And I call it "delegate.moveSliderDates (datePos: Int (roundedValue))" in the "MainMapVC" class.
Does anyone know where I failed in the statement of the delegate?Thanks :)
I attach the code of the two classes so that you see the whole code.
Class MainMapVC (first way):
import UIKit
protocol MainMapVCDelegate: class {
func moveSliderDates(datePos: Int)
}
class MainMapVC: UIViewController, UISearchBarDelegate, CLLocationManagerDelegate, GMSMapViewDelegate {
//MARK: VARIABLES
weak var delegate: MainMapVCDelegate? = nil
let step: Float = 1
@IBAction func moveSliderDates(_ sender: UISlider) {
let roundedValue = round(sender.value / step) * step
sender.value = roundedValue
delegate?.moveSliderDates(datePos: Int(roundedValue))
}
}
The delegate value inside the moveSliderDates function is "nil":
delegate?.moveSliderDates(datePos: Int(roundedValue))
Class LeftSideViewController (first way):
import UIKit
class LeftSideViewController: UIViewController, UITableViewDataSource, UITableViewDelegate, customCellDelegate, MainMapVCDelegate {
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "MainMapVC" {
let secondViewController = segue.destination as! MainMapVC
secondViewController.delegate = self
}
}
func moveSliderDates(datePos: Int){
print(datePos)
print("/////////////")
tableSideLeft.reloadData()
}
not enter inside this function because the delegate of "MainVC" is "nil":
Class MainMapVC (second way):
let step: Float = 1
@IBAction func moveSliderDates(_ sender: UISlider) {
let roundedValue = round(sender.value / step) * step
sender.value = roundedValue
let data:[String: Int] = ["data": Int(roundedValue)]
NotificationCenter.default.post(name: NSNotification.Name(rawValue: "notificationName"), object: nil, userInfo: data)
}
Class LeftSideViewController (second way):
func listnerFunction(_ notification: NSNotification) {
if let data = notification.userInfo?["data"] as? String {
print(data)
}
override func viewDidLoad() {
super.viewDidLoad()
NotificationCenter.default.addObserver(self, selector: #selector(listnerFunction(_:)), name: NSNotification.Name(rawValue: "notificationName"), object: nil)
}
Never goes into the function listnerFunction
You get the error because you defined your delegate as force unwrapped noy-nil version by this code
var delegate: LeftSideDelegate!
Instead, you need to change it like this. You should not create strong reference cycle for delegate.
Then for all your delegate calles, do the wrapped version delegate call
Other than that, change your line
protocol LeftSideDelegate {
intoprotocol LeftSideDelegate : class {
Passing data between view controllers using delegate
First, in the class where you want to pass the data to another view controller, declare protocol in this way
Then, create delegate variable as optional with type weak var. Call delegate method with you want to pass data or trigger action
Finally in your view controller that you want to receive action or data, implement the protocol. When you are initiating the second view controller, set it's delegate variable to be the current view controller
Passing data between view controllers using notification
In the destination view controller, register a handler function that is ready to be called. You can add this registration code in view did load
Then in another view controller, if you want to pass data, simply call this