Reputation:
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