swift - 当点击 tableview 的单元格时将用户引导到注释

标签 swift annotations tableview mapkit

简而言之,用户点击 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/

相关文章:

swift - SpriteKit 中的 MKMapView - Swift

ios - 如何实现 [example.text intValue]?

c# - 如何在 Xamarin 中填充 TableView ?

swift - MapView 优于 UITableViewCell

Swift - 更改tableView内mapview的高度

iOS/swift : Can't assign optional String to UILabel text property

ios - getter setter 模型类 Oop

iphone - 从自定义标注跳转到 MKMap 中的另一个标注

java - 创建对象时如何处理注释并设置默认值

java - Hibernate 在 Map 中映射 UserType