【问题标题】:Use MKAnnotation to move on the next View Controller使用 MKAnnotation 移动到下一个 View Controller
【发布时间】:2017-05-14 09:39:23
【问题描述】:

我是快速编程的新手。我想当用户点击 MKAnnotationPoint 移动到下一个视图控制器时。我现在的做法是按下 image1 顶部的“按钮”按钮。我的代码:

ma​​pViewController.swift

import UIKit
import MapKit
import CoreLocation

class mapViewController: UIViewController, UITextFieldDelegate, UIImagePickerControllerDelegate, UINavigationControllerDelegate, CLLocationManagerDelegate, MKMapViewDelegate {

    // MARK: Properties
    let pin = UIImage(named: "pin")
    var annotationTouched = String()
    var viaSegue = MKAnnotationView()

    // MARK: MAP
    @IBOutlet weak var mapView: MKMapView!


    let coreLocationManager = CLLocationManager()
    let locations = LocationList().Location

    // all locations will be stored on this array
    func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation])
    {
        let location = locations [0]

        //map zoomed
        let span:MKCoordinateSpan = MKCoordinateSpanMake(0.003, 0.003)
        //users location
        let myLocation:CLLocationCoordinate2D = CLLocationCoordinate2DMake(location.coordinate.latitude, location.coordinate.longitude)

        let region:MKCoordinateRegion = MKCoordinateRegionMake(myLocation, span)
        mapView.setRegion(region, animated: true)

        self.mapView.showsUserLocation = true
    }

    // func to change red pin to my custom pin
    func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView?
    {

        if let annotation = annotation as? Locations{
            if let view = mapView.dequeueReusableAnnotationView(withIdentifier: annotation.identifier){
                return view
            }else{
                let view = MKAnnotationView(annotation: annotation, reuseIdentifier: annotation.identifier)
                view.image = pin
                view.isEnabled = true
                view.canShowCallout = true
                //view.leftCalloutAccessoryView = UIImageView(image: pin)
                let btn = UIButton(type: .detailDisclosure)
                view.rightCalloutAccessoryView = btn

                return view
            }
        }
        return nil
    }

    // assigning the pin that is selected in the map to the annotation touched variable
    func mapView(_ mapView: MKMapView, didSelect view: MKAnnotationView)
    {
        if let annotation = view.annotation as? Locations {
            annotationTouched = annotation.title ?? "No title"
        }
    }


    override func viewDidLoad()
    {
        super.viewDidLoad()

        coreLocationManager.delegate = self
        //desired accuracy is the best accuracy, very accurate data for the location
        coreLocationManager.desiredAccuracy = kCLLocationAccuracyBest
        //request authorization from the user when user using my app
        coreLocationManager.requestWhenInUseAuthorization()

        coreLocationManager.startUpdatingLocation()

        mapView.delegate = self

        mapView.addAnnotations(locations)
    }

    // passing the name of the place on the next view controller which is the review view controller (RateViewController)
    override func prepare(for segue: UIStoryboardSegue, sender: Any?)
    {
        let destViewController : RateViewController = segue.destination as! RateViewController
        destViewController.placeLabelString = annotationTouched

    }


}

Locations.swift

import UIKit
import MapKit

class Locations: NSObject, MKAnnotation {
    // required coordinate, title, and the reuse identifier for this annotation
    var identifier = "locations"
    var title: String?
    var coordinate: CLLocationCoordinate2D
    //initializer taking a name, a latitude and longitude to populate the title and coordinate for each instance of this object
    init(name:String,lat:CLLocationDegrees,long:CLLocationDegrees){
        title = name
        coordinate = CLLocationCoordinate2DMake(lat, long)
    }

}
// Creating the list of the places that will be pinned in map
class LocationList: NSObject {
    var Location = [Locations]()
    override init(){
        Location += [Locations(name: "Dio Con Dio", lat: 40.590130, long: 23.036610)]
        Location += [Locations(name: "Paradosiako - Panorama", lat: 40.590102, long:23.036180)]
        Location += [Locations(name: "Veranda",  lat: 40.607740, long: 23.103044)]
        Location += [Locations(name: "Markiz",  lat: 40.634252, long: 22.936276)]
        Location += [Locations(name: "Moi Lounge Bar",  lat: 40.653481, long: 22.994131)]
        Location += [Locations(name: "Boulevard Lounge Bar",  lat: 40.658462, long: 22.983198)]
        Location += [Locations(name: "Ernést Hébrard",  lat: 40.631829, long: 22.941014)]
        Location += [Locations(name: "Tribeca - All Day & Night Bar",  lat: 40.631029, long: 22.942396)]

    }
}

【问题讨论】:

    标签: ios swift mapkit mkannotation mapkitannotation


    【解决方案1】:

    从你的mapViewController 到你的destination viewController 创建一个segue,然后这样做:

    func mapView(_ mapView: MKMapView, didSelect view: MKAnnotationView) {
        self.performSegue(withIdentifier: "destViewController", sender: nil)
    }
    

    Here 是我创建的一个示例项目,它向您展示了它是如何工作的。

    要编辑 segue 标识符,请执行以下操作:

    【讨论】:

    • 您如何找到您的withIdentifier: 值?
    • @RoulaChiouma,您可以通过单击 segue 将其设置在 StoryBoard 中,然后在右侧菜单中设置标识符。请参阅我刚刚添加的帖子中的图片。
    • 是的,但是在示例中,您还有另一个值。这就是我问的原因!您的视图控制器名称是 DestinationViewController 和您拥有的代码 ShowDestinationViewController
    • 我的第二个 viewControllers 名称是DestinationViewController,从我的MapViewController 到我的DestinationViewController 的segue 标识符称为ShowDestinationViewController。这是你问题的答案吗?我不完全确定我理解了这个问题。
    • 是的!以及如何添加这个 Storyboard Segue?我尝试了 ctrl + mouse 就像我在按钮上那样做,但做不到。
    【解决方案2】:

    将按钮与地图视图分开似乎是一种不恰当的做法。您应该使用注释视图上的按钮,例如您拥有的详细信息项目。当用户按下注释视图上的详细信息按钮时,下面的代码将转到添加评论控制器。您需要将 MKPointAnnotation 更改为您的 Locations,因为您尚未提供该自定义类的代码。

    import UIKit
    import MapKit
    import CoreLocation
    
    class MapViewController: UIViewController, CLLocationManagerDelegate, MKMapViewDelegate {
    
    
        @IBOutlet weak var mapView: MKMapView!
    
        let locationManager: CLLocationManager = {
    
            let manager = CLLocationManager()
    
            manager.requestWhenInUseAuthorization()
    
            manager.desiredAccuracy = kCLLocationAccuracyBest
    
            manager.startUpdatingLocation()
    
            return manager
        }()
    
        override func viewDidLoad() {
            super.viewDidLoad()
    
            // Do any additional setup after loading the view.
    
            self.locationManager.delegate = self
    
            self.mapView.addAnnotations(LocationList().Location)
        }
    
        func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
    
            // When the user's location updates, the map will be recentered on the user. This does the same as all your code.
    
            self.mapView.setUserTrackingMode(.follow, animated: true)
        }
    
        func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? {
    
            if let pin = annotation as? Locations {
    
                let view = mapView.dequeueReusableAnnotationView(withIdentifier: "pin") ?? MKPinAnnotationView(annotation: pin, reuseIdentifier: "pin")
    
                view.canShowCallout = true
    
                view.image = UIImage(named: "pin")
    
                let reviewButton = UIButton(type: .detailDisclosure)
    
                reviewButton.addTarget(self, action: #selector(self.addReview), for: .touchUpInside)
    
                view.rightCalloutAccessoryView = reviewButton
    
                return view
            }
    
            return nil
        }
    
        func addReview(){
            // This gets called with the detail declosure button is pressed.
    
            // This gets the selected pin.
            if let pin = self.mapView.selectedAnnotations.first as? Locations { 
                // This gets the view controller from your storyboard
                guard let vc = self.storyboard?.instantiateViewController(withIdentifier: "ReviewViewController") as? ReviewViewController else { return }
    
                // This passes the locations pin to the review view controller
                vc.pin = pin
    
                // This shows the review view controller
                self.navigationController?.pushViewController(vc, animated: true)
            }
        }
    }
    
    class ReviewViewController: UIViewController {
    
        @IBOutlet weak var locationLabel: UILabel!
    
        @IBOutlet weak var reviewTextField: UITextField!
    
        var pin: Locations!
    
        override func viewDidLoad() {
            super.viewDidLoad()
    
            self.navigationItem.title = "Write a Review"
    
            self.locationLabel.text = pin.title
    
            let sendButton = UIBarButtonItem(title: "Send", style: .done, target: self, action: #selector(self.submitReview))
    
            self.navigationItem.rightBarButtonItem = sendButton
        }
    
        func submitReview(){
    
            print("Your review is: \(self.reviewTextField.text ?? "Why didn't you write anything?")")
        }
    }
    
    class Locations: NSObject, MKAnnotation {
    
        var title: String?
    
        var coordinate: CLLocationCoordinate2D
    
        init(name:String,lat:CLLocationDegrees,long:CLLocationDegrees){
    
            title = name
    
            coordinate = CLLocationCoordinate2DMake(lat, long)
        }
    }
    
    class LocationList: NSObject {
    
        var Location = [Locations]()
    
        override init(){
    
            Location += [Locations(name: "Dio Con Dio", lat: 40.590130, long: 23.036610)]
            Location += [Locations(name: "Paradosiako - Panorama", lat: 40.590102, long:23.036180)]
            Location += [Locations(name: "Veranda",  lat: 40.607740, long: 23.103044)]
            Location += [Locations(name: "Markiz",  lat: 40.634252, long: 22.936276)]
            Location += [Locations(name: "Moi Lounge Bar",  lat: 40.653481, long: 22.994131)]
            Location += [Locations(name: "Boulevard Lounge Bar",  lat: 40.658462, long: 22.983198)]
            Location += [Locations(name: "Ernést Hébrard",  lat: 40.631829, long: 22.941014)]
            Location += [Locations(name: "Tribeca - All Day & Night Bar",  lat: 40.631029, long: 22.942396)]
        }
    }
    

    【讨论】:

    • 我编辑了那个!我添加了自定义类!但我认为你的代码太复杂了。必须有一种最简单的方法来单击详细信息项以在下一个视图控制器上移动。
    • 我已经简化了一些,但这并不复杂。 addReview 函数是我唯一添加的。我还重新创建了你的另一个视图控制器来测试它,但这正是你需要的功能。
    • @TristanBeaton 我是否理解正确,如果按下右侧的信息图标,您的代码将打开下一个视图控制器?如果是这样,有什么方法可以在按下文本本身时获得相同的效果?
    • @dopexxx 我认为你是对的。您可以向 MKAnnotationView 添加轻击手势,该手势将检测到带有该视图(包括文本)的任何位置的轻击。但我不知道是否有一种方法可以在不创建自定义注释视图的情况下让文本可点击。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-09-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-11-23
    相关资源
    最近更新 更多