user23509100
user23509100

Reputation:

Dropping Pin into Map view when table view cell is selected

I have created search bar with table view. What I am trying to achieve now is when the table view didSelectRowAt function is called , I want to navigate into map view and show the pin into map view based on the latitude and longitude is passed form table view didSelectRowAt function. I have created delegate into map view.

 protocol HandleMapSearch: AnyObject {
    func dropPinZoomIn(placemark: MKPlacemark)
}

I am trying to call it form initial view controller at didSelectRowAt like this way .

self.handleMapSearch?.dropPinZoomIn(placemark: (response?.mapItems[0].placemark)!)

But I am facing difficulties to pass it into map view controller. Currently I am passing some hardcoded value into map view controller. But I am not sure How can I pass the latitude and longitude form didSelectRowAt function and show the pin into map view controller.

Here is the initial view controller code.

class ViewController: UIViewController, UISearchBarDelegate, MKLocalSearchCompleterDelegate {

    @IBOutlet weak var searchBar: UISearchBar!
    @IBOutlet weak var searchResultsTable: UITableView!
    
    var searchCompleter = MKLocalSearchCompleter()
    var searchResults = [MKLocalSearchCompletion]()
    weak var handleMapSearch: HandleMapSearch?

    override func viewDidLoad() {
        super.viewDidLoad()
        
        searchCompleter.delegate = self
        searchBar?.delegate = self
        searchResultsTable?.delegate = self
        searchResultsTable?.dataSource = self
    }

    func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) {
        searchCompleter.queryFragment = searchText
    }
    
    func completerDidUpdateResults(_ completer: MKLocalSearchCompleter) {
        
        searchResults = completer.results
        searchResultsTable.reloadData()
    }
    
    func completer(_ completer: MKLocalSearchCompleter, didFailWithError error: Error) {
        // Error
    }
}

extension ViewController: UITableViewDataSource {
    func numberOfSections(in tableView: UITableView) -> Int {
        return 1
    }
    
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return searchResults.count
    }
    
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        
        let searchResult = searchResults[indexPath.row]
        let cell = UITableViewCell(style: .subtitle, reuseIdentifier: nil)
        cell.textLabel?.text = searchResult.title
        cell.detailTextLabel?.text = searchResult.subtitle
        return cell
    }
}

extension ViewController: UITableViewDelegate {
  
    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        
        let result = searchResults[indexPath.row]
        let searchRequest = MKLocalSearch.Request(completion: result)
        let search = MKLocalSearch(request: searchRequest)
        search.start { (response, error) in
        guard let coordinate = response?.mapItems[0].placemark.coordinate else { return }
        guard let name = response?.mapItems[0].name else { return }
        let lat = coordinate.latitude
        let lon = coordinate.longitude
        self.handleMapSearch?.dropPinZoomIn(placemark: (response?.mapItems[0].placemark)!)
        let vc = UIStoryboard.init(name: "Main", bundle: Bundle.main).instantiateViewController(withIdentifier: "MapViewController") as! MapViewController
        self.navigationController?.pushViewController(vc, animated: true)
        }
    }
}

Here is my map view controller.

import UIKit
import MapKit
import Contacts

protocol HandleMapSearch: AnyObject {
    func dropPinZoomIn(placemark: MKPlacemark)
}

class MapViewController: UIViewController {

    @IBOutlet weak var myMapView: MKMapView!
    weak var handleMapSearch: HandleMapSearch?
    let coords = CLLocationCoordinate2DMake(51.5083, -0.1384)
    let address = [CNPostalAddressStreetKey: "181 Piccadilly, St. James's", CNPostalAddressCityKey: "London", CNPostalAddressPostalCodeKey: "W1A 1ER", CNPostalAddressISOCountryCodeKey: "GB"]

    override func viewDidLoad() {
        super.viewDidLoad()
        let place = MKPlacemark(coordinate: coords, addressDictionary: address)

        dropPinZoomIn(placemark: place)
    }
}

extension MapViewController: HandleMapSearch {
    
    func dropPinZoomIn(placemark: MKPlacemark) {
        // clear existing pins
        myMapView.removeAnnotations(myMapView.annotations)
        let annotation = MKPointAnnotation()
        annotation.coordinate = placemark.coordinate
        annotation.title = placemark.name
        if let city = placemark.locality, let state = placemark.administrativeArea {
        annotation.subtitle = "(city) (state)"
        }
        myMapView.addAnnotation(annotation)
        let span = MKCoordinateSpan(latitudeDelta: 0.05, longitudeDelta: 0.05)
        let region = MKCoordinateRegion(center: placemark.coordinate, span: span)
        myMapView.setRegion(region, animated: true)
    }
}

Upvotes: 0

Views: 34

Answers (0)

Related Questions