0

I am creating something similar to Apple Maps' bottom sheet which is discussed here: How to mimic iOS 10 maps bottom sheet

I worked through creating a child view infoViewController.xib (InfoViewController.swift - code and InfoViewController.xib - design of view) This Child view will appear in front of my map just like the Apple Maps example so you can still see the map behind it.

The mapView is controlled by MapViewController.swift, I use the following code to call it from there:

func addInfoView() {

    let infoVC = InfoViewController()

    self.addChildViewController(infoVC)
    self.view.addSubview(infoVC.view)
    infoVC.didMove(toParentViewController: self)
}

I set up a 'directions' button on this view as an IBAction. When this button is pressed I want it to create directions and display them on the map in MapViewController. The destination and current location information is passed via UserDefaults to infoViewController. I have it 'working':

@IBAction func infoDirectionButton(_ sender: Any) {

   /*here i have it getting current and destination locations*/


    let storyboard: UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
    let mapViewController = storyboard.instantiateViewController(withIdentifier: "MapViewController") as! MapViewController

    self.present(mapViewController, animated: false)

    //routeDirection Method is in MapViewController and handles the direction requests    
    mapViewController.routeDirections(current: current, destination: destination)

     mapViewController.addInfoView()

}

This results in the directions being shown on the screen, however not before the screen flashing as it reloads my mapView and the infoView (child view).

Is there a way I can get it to display the directions without reloading both the parent view and child view.

the 'self.present' code is needed so I can call the method in that ViewController, it also wont display the directions on the map either.

self.present(mapViewController, animated: false)

and addInfoView() to reload the child view after the directions have been displayed. Otherwise it is not shown again

mapViewController.addInfoView()

Apologies if this is hard to follow, I have tried to simplify the code to highlight the issue.

Jay Patel
  • 2,642
  • 2
  • 18
  • 40
Pobbin
  • 33
  • 6

2 Answers2

0

The first thing that comes to my mind is that you can add notification where you find and set directions. After that you can observe that notification from controller which have your map.

B.Uyar
  • 51
  • 3
  • Thanks for the suggestion I will try that. I already use a notification to update the child view if it is already displayed. I was pulling my hair out trying to sort this so thank you so much @B.Uyar – Pobbin Jan 19 '18 at 12:10
  • quick follow up question regarding how to set up child view. My class for the child view is: `class InfoViewController: UIViewController, CLLocationManagerDelegate {` is this the correct way to do this? Ive read somewhere it should be `class InfoViewController: MapViewController {` – Pobbin Jan 19 '18 at 23:04
0

As Suggested by @B.Uyar I implemented NotificationCenter.default.postto the directions button on the Child View and NotificationCenter.default.addObserver in the ViewDidLoad of the Parent.

I noticed that the notification observer was being called multiple times (Same number of times that I had left and returned to the map screen)

I read NSNotificationCenter calling two times which informed me that i needed to use a remove Observer when the view was not in use. so:

    override func viewWillDisappear(_ animated: Bool) {
        NotificationCenter.default.removeObserver(self, name: NSNotification.Name(rawValue: "name"), object: nil)
    }

This looks like it is working as desired. This Thread may be summarising a few others but I reckon it might still be useful for anyone who follows a similar thought process.

Pobbin
  • 33
  • 6