Короче говоря, пользователь касается строки в виде таблицы (которая содержит данные из местоположения), и я хочу отобразить карту с соответствующей аннотацией, когда пользователь касается строки. Пока не повезло.
Я реализовал предложения по использованию шаблона делегата. Теперь, когда я это реализовал, приложение продолжает падать.
Я опубликую код, но после просмотра десятков вопросов о переполнении стека я не смогу его решить. Надеюсь, вы, ребята, можете помочь!
// ГЛАВНЫЙ КОНТРОЛЛЕР
import UIKit
import MapKit
import CoreLocation
class ViewController: UIViewController, CLLocationManagerDelegate, UISearchBarDelegate {
override func viewDidLoad() {
super.viewDidLoad()
}
//SearchTable initiation
let searchTable = storyboard!.instantiateViewController(withIdentifier: "SearchTableViewController") as! SearchTableViewController
searchController = UISearchController(searchResultsController: searchTable)
searchController?.searchResultsUpdater = searchTable
searchController?.hidesNavigationBarDuringPresentation = false
searchController?.dimsBackgroundDuringPresentation = true
searchController?.definesPresentationContext = true
//Searchbar initiation
let searchBar = searchController!.searchBar
searchBar.sizeToFit()
searchBar.keyboardAppearance = UIKeyboardAppearance.dark
searchBar.placeholder = "Search locations"
navigationItem.titleView = searchController?.searchBar
searchBar.delegate = self
searchTable.mapView = mapView
searchTable.handleMapSearchDelegate = self
}
//Update the map
func updateMap(_ location: CLLocation) {
let region = MKCoordinateRegion.init(center: location.coordinate, latitudinalMeters: 1000, longitudinalMeters: 1000)
mapView.setRegion(region, animated: true)
}
//Cancel searchBar
func searchBarCancelButtonClicked(_ searchBar: UISearchBar) {
searchBar.text = nil
searchBar.setShowsCancelButton(false, animated: true)
searchBar.endEditing(true)
}
}
//Center the map on current user's location
extension ViewController: MKMapViewDelegate {
func centerMapOnUserLocation() {
guard let coordinate = locationManager.location?.coordinate else { return }
let coordinateRegion = MKCoordinateRegion(center: coordinate, latitudinalMeters: regionRadius * 2.0, longitudinalMeters: regionRadius * 2.0)
mapView.setRegion(coordinateRegion, animated: true)
}
}
//Zoom into selected location from search
extension ViewController: HandleMapSearch {
func dropPinZoomIn(placemark: MKAnnotation) {
updateMap(CLLocation(latitude: placemark.coordinate.latitude, longitude: placemark.coordinate.longitude))
searchController.searchBar.text = placemark.title!
}
}
//Zoom into selected location from selectedRow
extension ViewController: HandleSelectedLocation {
func dropPinAndZoomIn(placemark: MKAnnotation) {
updateMap(CLLocation(latitude: placemark.coordinate.latitude, longitude: placemark.coordinate.longitude))
}
}
// TABLEVIEWCONTROLLER
import UIKit
import MapKit
protocol HandleSelectedLocation {
func dropPinAndZoomIn(placemark: MKAnnotation)
}
//Initialize the TableViewController
class CategoriesController: UIViewController, UITableViewDataSource, UITableViewDelegate {
//Variables
var mapView: MKMapView?
var selectedItem = [MKAnnotation]()
var handleSelectedLocationDelegate: HandleSelectedLocation? = nil
//Outlet
@IBOutlet var tableView: UITableView!
//Load view
override func viewDidLoad() {
super.viewDidLoad()
tableView.dataSource = self
tableView.delegate = self
}
func numberOfSectionsInTableView(tableView: UITableView) -> Int {
return 1
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return location.count
}
//Fill cells with locations
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "allCell") ?? UITableViewCell(style: .subtitle, reuseIdentifier: "allCell")
let locations = location[indexPath.row]
cell.textLabel?.text = locations.title
cell.textLabel?.textColor = UIColor.white
cell.detailTextLabel?.text = locations.rating
cell.detailTextLabel?.textColor = UIColor.white
return cell
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let annotation = mapView!.annotations
let locationSelected = annotation[indexPath.row]
handleSelectedLocationDelegate?.dropPinAndZoomIn(placemark: locationSelected)
tableView.isHidden = true
}
}
// SEARCHTABLEVIEWCONTROLLER
**protocol HandleMapSearch {
func dropPinZoomIn(placemark: MKAnnotation)
}
//Make searches appear
class SearchTableViewController: UITableViewController, UISearchResultsUpdating, UISearchBarDelegate {
//Variables
var mapView: MKMapView? = nil
var matchingItems = [MKAnnotation]()
var handleMapSearchDelegate: HandleMapSearch? = nil
func updateSearchResults(for searchController: UISearchController) {
guard let _ = mapView,
let searchBarText = searchController.searchBar.text else { return }
matchingItems = self.mapView!.annotations.filter { annotation -> Bool in
if annotation.title!?.range(of: searchBarText, options: .caseInsensitive) != nil {
return true
}
if annotation.subtitle!?.range(of: searchBarText, options: .caseInsensitive) != nil {
return true
}
return false
}
self.tableView.reloadData()
}
override func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return matchingItems.count
}
//Fill tableView with location provided by search
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell") ?? UITableViewCell(style: .subtitle, reuseIdentifier: "cell")
let selectedItem = matchingItems[indexPath.row]
cell.textLabel?.text = selectedItem.title!
cell.textLabel?.textColor = UIColor.white
cell.detailTextLabel?.text = selectedItem.subtitle!
cell.detailTextLabel?.textColor = UIColor.white
return cell
}
//Go to map and show selected annotation
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let selectedItem = matchingItems[indexPath.row]
handleMapSearchDelegate?.dropPinZoomIn(placemark: selectedItem)
dismiss(animated: true, completion: nil)
}
}**
// CustomAnnotation
import Foundation
import MapKit
class CustomAnnotation: NSObject, MKAnnotation {
var coordinate: CLLocationCoordinate2D
var extraDescription: String?
var title: String?
var subtitle: String?
var country: String?
init(coordinate: CLLocationCoordinate2D) {
self.coordinate = coordinate
}
}
// Структура размещения
import Foundation
import UIKit
import MapKit
//Annotations
struct SomeLocation {
let title: String
let rating: String
let description: String
let country: String
let latitude: Double
let longitude: Double
}
ВОПРОС: Правильно ли реализован шаблон делегата?
Когда я добавил последнее расширение, у меня возникла проблема с запуском приложения. После отмены этого изменения это сработало, но, конечно, делегат ничего не сделал.
Если вам нужны какие-либо пояснения или дополнительный код, пожалуйста, спросите.
Я не могу решить эту проблему, вся помощь очень ценится!