Swift 点击tableview的单元格时,将用户指向注释
简而言之,用户点击tableview中的一行(其中包含来自某个位置的数据),我希望在用户点击该行时显示带有适当注释的地图。到目前为止没有运气。 我已经实现了使用委托模式的建议。现在我已经实现了它,应用程序不断崩溃 我将发布代码,但在浏览了几十个堆栈溢出问题后,我无法解决它。希望你们能帮忙 //主控制器Swift 点击tableview的单元格时,将用户指向注释,swift,annotations,tableview,mapkit,Swift,Annotations,Tableview,Mapkit,简而言之,用户点击tableview中的一行(其中包含来自某个位置的数据),我希望在用户点击该行时显示带有适当注释的地图。到目前为止没有运气。 我已经实现了使用委托模式的建议。现在我已经实现了它,应用程序不断崩溃 我将发布代码,但在浏览了几十个堆栈溢出问题后,我无法解决它。希望你们能帮忙 //主控制器 import UIKit import MapKit import CoreLocation class ViewController: UIViewController, CLLocation
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
}
}
**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)
}
}**
//TABLEVIEWCONTROLLER
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
}
}
**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)
}
}**
//SEARCHTABLEVIEWCONTROLLER
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
}
}
**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
}
问题:我是否正确实现了委托模式?
当我添加最后一个扩展时,它给了我启动应用程序的问题。在扭转了这个变化之后,它起了作用,但当然,该代表什么也没做
如果您需要任何澄清或额外代码,请询问
我似乎无法解决这个问题,非常感谢大家的帮助 代理模式如何 e、 g 主视图控制器:
...
let vc = SecondViewController
vc.delegate = self
...
extension MainViewController: SecondViewControllerDelegate {
func didSelectRow(at: YourLocationType) {
// Direct user to annotation when cell of tableview tapped
}
}
委托模式如何 e、 g 主视图控制器:
...
let vc = SecondViewController
vc.delegate = self
...
extension MainViewController: SecondViewControllerDelegate {
func didSelectRow(at: YourLocationType) {
// Direct user to annotation when cell of tableview tapped
}
}
尝试委托模式。在tableview上,点击调用主视图控制器的方法,将引用传递给所需的location@pckill的模式是实现这种实现的好方法。如果您在实现它时遇到困难,请与我们分享您的代码,我们可以提供帮助。@pckill您能看看我更新的代码吗?我曾尝试实现委托模式,但应用程序不断崩溃。“我很抱歉反应太晚,但我有一些紧急的个人情况需要处理。”JamieCoenen,阅读。请在寻求帮助时提供帮助。例如,这个
searchController
是什么?您在哪里初始化它?@pckill我已经添加了searchBar
/searchController
(它来自UISearchBar类型)中的代码以及其他一些片段,以明确它是如何工作的。对于意外发现的nil,只有在添加扩展名HandleSelectedLocation
时才会发生这种情况,否则这一行执行时不会出现问题。请尝试委托模式。在tableview上,点击调用主视图控制器的方法,将引用传递给所需的location@pckill的模式是实现这种实现的好方法。如果您在实现它时遇到困难,请与我们分享您的代码,我们可以提供帮助。@pckill您能看看我更新的代码吗?我曾尝试实现委托模式,但应用程序不断崩溃。“我很抱歉反应太晚,但我有一些紧急的个人情况需要处理。”JamieCoenen,阅读。请在寻求帮助时提供帮助。例如,这个searchController
是什么?您在哪里初始化它?@pckill我已经添加了searchBar
/searchController
(它来自UISearchBar类型)中的代码以及其他一些片段,以明确它是如何工作的。对于意外发现的nil,只有在我添加扩展名HandleSelectedLocation
时才会发生这种情况,否则这行执行时不会出现问题。感谢您的回答!你能看一下更新的代码吗?我已经实现了委托模式,但不知何故它似乎不起作用。谢谢你的回答!你能看一下更新的代码吗?我已经实现了委托模式,但不知何故它似乎不起作用。