简而言之,用户点击 TableView 中的一行(其中包含来自某个位置的数据),我想在用户点击该行时显示带有适当注释的 map 。到目前为止没有运气。
我已经实现了使用委托(delegate)模式的建议。现在我已经实现了它,应用程序一直在崩溃。
我会贴出代码,但是翻了几十个stack overflow的问题,还是没法解决。希望大家帮帮忙!
//主 Controller
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))
}
}
// TableView Controller
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)
}
}**
//自定义注释
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
}
问题: 我是否正确实现了委托(delegate)模式? 当我添加最后一个扩展时,它给我带来了启动应用程序的问题。撤消该更改后,它起作用了,但代表当然没有做任何事情。
如果您需要任何说明或额外的代码,请询问。
我似乎无法解决这个问题,非常感谢所有帮助!
最佳答案
委托(delegate)模式怎么样?
例如
protocol SecondViewControllerDelegate: class {
func didSelectRow(at: YourLocationType)
}
class SecondViewController: UITableViewController {
weak var delegate: SecondViewControllerDelegate?
...
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
// Get the location
delegate?.didSelectRow(at: location)
}
...
}
主视图 Controller :
...
let vc = SecondViewController
vc.delegate = self
...
extension MainViewController: SecondViewControllerDelegate {
func didSelectRow(at: YourLocationType) {
// Direct user to annotation when cell of tableview tapped
}
}
关于swift - 当点击 tableview 的单元格时将用户引导到注释,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54181113/