【问题标题】:Direct user to annotation when cell of tableview tapped当点击表格视图的单元格时引导用户进行注释
【发布时间】:2019-01-14 11:58:28
【问题描述】:

简而言之,用户点击表格视图中的一行(其中包含来自某个位置的数据),我想在用户点击该行时显示带有适当注释的地图。到目前为止没有运气。

我已经实施了使用委托模式的建议。现在我已经实现了它,应用程序不断崩溃。

我会贴出代码,但是浏览了几十个堆栈溢出问题后,我无法解决。希望大家帮忙!

//主控制器

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))
    }
}

// 表视图控制器

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
}

问题: 我是否正确实现了委托模式? 当我添加最后一个扩展时,它给了我启动应用程序的问题。撤消该更改后,它起作用了,但代表当然没有做任何事情。

如果您需要任何说明或额外代码,请询问。

我似乎无法解决这个问题,非常感谢所有帮助!

【问题讨论】:

  • 尝试委托模式。在 tableview 点击调用主视图控制器的方法,传递对所需位置的引用
  • @pckill 的模式是实现这种实现的好方法。如果您很难实现它,请分享您的代码,我们可以提供帮助。
  • @pckill 你能看看我更新的代码吗?我试图实现委托模式,但应用程序不断崩溃。对于迟到的回复,我深表歉意,但我有一些紧急的个人情况需要处理。
  • @JamieCoenen,了解unexpectedly found nil。寻求帮助时请提供minimal, complete and verifiable example。例如,searchController 是什么,你在哪里初始化它?
  • @pckill 我已经添加了来自searchBar/searchController 的代码(它来自 UISearchBar 类型)和更多的部分来真正阐明它是如何工作的。至于意外发现的nil,只有当我添加扩展名HandleSelectedLocation时才会发生这种情况,否则此行执行没有问题。

标签: swift annotations tableview mapkit


【解决方案1】:

委托模式怎么样?

例如

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)
    }

    ...
}

主视图控制器:

...
let vc = SecondViewController
vc.delegate = self
...

extension MainViewController: SecondViewControllerDelegate {
    func didSelectRow(at: YourLocationType) {
        // Direct user to annotation when cell of tableview tapped
    }
}

【讨论】:

  • 感谢您的回答!你能看看更新的代码吗?我已经实现了委托模式,但不知何故它似乎不起作用。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多