I have two map View controllers, in first view controller i am fetching current location and auto filling some values and showing them in related textfields.
And in second view controller i am searching new location and sending its location values to first view controller using DataEnteredDelegate
method now how to replace delegate method values in current location values in first view controller.
here i am getting second view controller values:
func userDidEnterInformation(info: [String]) {
print("zoom map address viewcontroller data \(info)")
}
Prints: zoom map address viewcontroller data '["560066", "Auto Nagar", "Bangalore"]'
how to replace 560066
in self.pincodeField.text
and Auto Nagar
in self.streetField.text
and Bangalore
in self.cityField.text
in first view controller
first view controller code:
class ProfileAddressViewController: UIViewController, CLLocationManagerDelegate, UISearchBarDelegate, DataEnteredDelegate {
@IBOutlet weak var pincodeField: UITextField!
@IBOutlet weak var cityField: UITextField!
@IBOutlet weak var streetField: UITextField!
@IBOutlet weak var storeNoField: UITextField!
@IBOutlet weak var colonyField: UITextField!
@IBOutlet weak var landmarkField: UITextField!
@IBOutlet weak var mapView: MKMapView!
let annotation = MKPointAnnotation()
let locationManager = CLLocationManager()
var latitude: String?
var logitude: String?
override func viewDidLoad() {
super.viewDidLoad()
self.locationManager.requestAlwaysAuthorization()
if CLLocationManager.locationServicesEnabled() {
locationManager.delegate = self
locationManager.desiredAccuracy = kCLLocationAccuracyNearestTenMeters
locationManager.startUpdatingLocation()
}
}
override func viewWillAppear(_ animated: Bool) {
self.navigationController?.navigationBar.isHidden=true;
let tapGesture = UITapGestureRecognizer(target: self, action: #selector(self.triggerTouchAction(_:)))
mapView.addGestureRecognizer(tapGesture)
}
@objc func triggerTouchAction(_ sender: UITapGestureRecognizer) {
print("Please Help!")
let viewController = self.storyboard?.instantiateViewController(withIdentifier: "NewZoomAddressViewController") as! NewZoomAddressViewController;
viewController.delegate = self
viewController.zipName = self.pincodeField.text
viewController.sublocalityName = self.colonyField.text
viewController.localityName = self.cityField.text
self.navigationController?.pushViewController(viewController, animated: true);
}
func userDidEnterInformation(info: [String]) {
print("zoom map address viewcontroller data \(info)")
}
@IBAction func submitButtonClicked(_ sender: UIButton) {
self.view.endEditing(true)
let viewController = self.storyboard?.instantiateViewController(withIdentifier: "NewZoomAddressViewController") as! NewZoomAddressViewController;
self.navigationController?.pushViewController(viewController, animated: true);
}
func locationManager(_ manager: CLLocationManager, didFailWithError error: Error) {
print(error)
}
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
guard let _: CLLocationCoordinate2D = manager.location?.coordinate else { return }
let userLocation :CLLocation = locations[0] as CLLocation
latitude = "\(userLocation.coordinate.latitude)"
logitude = "\(userLocation.coordinate.longitude)"
let geocoder = CLGeocoder()
geocoder.reverseGeocodeLocation(userLocation) { (placemarks, error) in
if (error != nil){
print("error in reverseGeocode")
}
let placemark = placemarks! as [CLPlacemark]
if placemark.count>0{
let placemark = placemarks![0]
print(placemark.administrativeArea!)
print(placemark.country!)
let placemarkDictonary: NSDictionary=placemark.addressDictionary as! NSDictionary
self.pincodeField.text=placemarkDictonary["ZIP"] as? String
self.cityField.text=placemarkDictonary["City"] as? String
self.streetField.text=placemarkDictonary["Street"] as? String
self.colonyField.text=placemarkDictonary["SubLocality"] as? String
self.landmarkField.text=placemarkDictonary["SubThoroughfare"] as? String
}
}
let center = CLLocationCoordinate2D(latitude: userLocation.coordinate.latitude, longitude: userLocation.coordinate.longitude)
let region = MKCoordinateRegion(center: center, span: MKCoordinateSpan(latitudeDelta: 0.01, longitudeDelta: 0.01))
mapView.setRegion(region, animated: true)
// Drop a pin at user's Current Location
let myAnnotation: MKPointAnnotation = MKPointAnnotation()
myAnnotation.coordinate = CLLocationCoordinate2DMake(userLocation.coordinate.latitude, userLocation.coordinate.longitude);
myAnnotation.title = "Current location"
mapView.addAnnotation(myAnnotation)
locationManager.stopUpdatingLocation()
}
func locationManager(_ manager: CLLocationManager, didChangeAuthorization status: CLAuthorizationStatus) {
switch status {
case .notDetermined:
print("User still thinking")
case .denied:
print("User hates you")
case .authorizedWhenInUse:
locationManager.stopUpdatingLocation()
case .authorizedAlways:
locationManager.startUpdatingLocation()
case .restricted:
print("User dislikes you")
}
}
}
Next view controller code:
protocol DataEnteredDelegate: class {
func userDidEnterInformation(info: [String])
}
class NewZoomAddressViewController: UIViewController {
weak var delegate: DataEnteredDelegate? = nil
var userModel : ProfileModel?
var zipName: String?
var localityName: String?
var sublocalityName: String?
@IBOutlet weak var mapView: MKMapView!
@IBOutlet weak var addressLabel: UILabel!
override func viewDidLoad() {
super.viewDidLoad()
print("in Zoom map VC")
mapView.delegate = self
addressLabel.text = "\(self.sublocalityName!) \(localityName!) \(self.zipName!)"
}
@IBAction func confirmBtn(_ sender: Any) {
delegate?.userDidEnterInformation(info: [zipName!,sublocalityName!, localityName!])
self.navigationController?.popViewController(animated: true)
}
You were almost there. Just set the values to your textfields in your userDidEnterInformation(:)
func:
func userDidEnterInformation(info: [String]) {
self.pincodeField.text = info[0]
self.streetField.text = info[1]
self.cityField.text = info[2]
}
However, accessing the String array subscripts with a number might lead to errors, I would suggest the following approach for you:
struct DataEnteredModel {
let pinCode: String
let streetField: String
let cityField: String
}
Change the function type in your delegate method from func userDidEnterInformation(info: [String])
to func userDidEnterInformation(info: DataEnteredModel)
In confirmBtn(_:9
, call the delegate function this way:
@IBAction func confirmBtn(_ sender: Any) {
guard
let zipName = zipName,
let sublocalityName = sublocalityName,
let localityName = localityName
else { return }
let enteredData = DataEnteredModel(pinCode: zipName, streetField: sublocalityName, cityField: localityName)
delegate?.userDidEnterInformation(info: enteredData)
}
userDidEnterInformation
method in ProfileAddressViewController
you have to do:func userDidEnterInformation(info: DataEnteredModel) {
self.pincodeField.text = info.pinCode
self.streetField.text = info.streetField
self.cityField.text = info.cityField
}
That should be it, in case of questions, feel free to ask!