Ios swift自定义地图类

Ios swift自定义地图类,ios,swift,mapkit,segue,Ios,Swift,Mapkit,Segue,我正在学习Swift,希望创建MKMapKit的子类来封装一些特定的功能,比如检查两点之间的距离,创建自定义注释,并将所有地图代码分离到一个类中 我创建了一个类: class GameMapViewController: MKMapView, MKMapViewDelegate{...} 我在主视图控制器的代码中启动该类(并将其作为子视图添加到情节提要上的视图中,以便我可以更轻松地控制其位置): 这将所有设置都设置为ok,并且所有工作正常,但当我想从自定义注释触发序列时除外: func map

我正在学习Swift,希望创建MKMapKit的子类来封装一些特定的功能,比如检查两点之间的距离,创建自定义注释,并将所有地图代码分离到一个类中

我创建了一个类:

class GameMapViewController: MKMapView, MKMapViewDelegate{...}
我在主视图控制器的代码中启动该类(并将其作为子视图添加到情节提要上的视图中,以便我可以更轻松地控制其位置):

这将所有设置都设置为ok,并且所有工作正常,但当我想从自定义注释触发序列时除外:

func mapView(mapView: MKMapView!, didSelectAnnotationView view: MKAnnotationView!) {...}
当我点击注释标注时,
didSelectAnnotationView
会被调用,但没有任何内容具有我正在寻找的方法
performsguewithIdentifier
,所有问题都表明我应该使用该方法

(我尝试将MapKit视图放到情节提要上,并将其类更改为使用
GameMapViewController
,但没有启动任何init函数)

我猜这与我如何初始化自定义类有关

MainViewController.swift:

override func viewDidLoad() {
super.viewDidLoad()
....
// Create the game map
gameMap = GameMapViewController(container: mapViewHolder)
mapViewHolder.addSubview(gameMap)

...

}
import UIKit
import MapKit


class GameMapViewController: MKMapView, MKMapViewDelegate{

var spanQuestion:MKCoordinateSpan = MKCoordinateSpanMake(180, 180)
var spanAnswer:MKCoordinateSpan = MKCoordinateSpanMake(180, 180)
var hasUserCityLocationGuess: Bool = false

var containingView: UIView

override init(){
    println ("GameMapViewController init")
    containingView = UIView()
    super.init(frame: CGRect(x: 0, y: 0, width: 1000, height: 1000))

    self.delegate=self
    var latDeltaAnswer:CLLocationDegrees = 50
    var lngDeltaAnswer:CLLocationDegrees = 50
    spanAnswer = MKCoordinateSpanMake(latDeltaAnswer, lngDeltaAnswer)

    var latDeltaQuestion:CLLocationDegrees = 180
    var lngDeltaQuestion:CLLocationDegrees = 180
    spanQuestion = MKCoordinateSpanMake(latDeltaQuestion, lngDeltaQuestion)



}

required init(coder aDecoder: NSCoder) {
    containingView = UIView()
    super.init(coder: aDecoder)
    self.delegate = nil
    println ("GameMapViewController init with decoder")
}


convenience init(container: UIView) {
    println ("GameMapViewController convenience")
    self.init()
    self.delegate = self
    containingView = container


}

func mapViewDidFinishLoadingMap(mapView: MKMapView!) {
    println("mapViewDidFinishLoadingMap")
}

func mapViewWillStartLoadingMap(mapView: MKMapView!) {

    self.frame = CGRect (x: 0, y: 0, width: containingView.frame.width, height: containingView.frame.height)
    self.contentMode = UIViewContentMode.ScaleAspectFill
    superview?.sizeToFit()
    var guessPlaceRecognizer = UILongPressGestureRecognizer(target: self, action: "guessPlace:")
    guessPlaceRecognizer.minimumPressDuration = 1.0
    mapView.addGestureRecognizer(guessPlaceRecognizer)
    mapView.mapType = MKMapType.Satellite

}

func mapView(mapView: MKMapView!, rendererForOverlay overlay: MKOverlay!) -> MKOverlayRenderer! {
    if overlay is MKCircle {
        var circleRenderer = MKCircleRenderer(overlay: overlay)
        circleRenderer.strokeColor = UIColor.redColor()
        circleRenderer.fillColor = UIColor(red: 255, green: 0, blue: 0, alpha: 0.1)
        circleRenderer.lineWidth = 1
        //userOverlayCircleRender = circleRenderer
        return circleRenderer
    } else {
        return nil
    }
}

func guessPlace(gestureRecognizer:UIGestureRecognizer){

    let guessPlaceFirst = NSUserDefaults.standardUserDefaults().boolForKey("guess_place_preference")

    if guessPlaceFirst {
        var touchPoint = gestureRecognizer.locationInView(self)
        var newCoord:CLLocationCoordinate2D = self.convertPoint(touchPoint, toCoordinateFromView: self)
        var userAnnotation = UserPointAnnotation()
        userAnnotation.coordinate = newCoord
        self.addAnnotation(userAnnotation)


        var getLat: CLLocationDegrees = newCoord.latitude
        var getLon: CLLocationDegrees = newCoord.longitude
        var circleCenter: CLLocation =  CLLocation(latitude: getLat, longitude: getLon)
        addRadiusCircle(circleCenter)
        hasUserCityLocationGuess = true
    }

}

func showCity() {
    let location = CLLocationCoordinate2D(latitude: (currentCity["latitude"]! as CLLocationDegrees), longitude: (currentCity["longitude"]! as CLLocationDegrees))
    let region:MKCoordinateRegion = MKCoordinateRegionMake(location, self.spanAnswer)
    let city: String = currentCity["city"]! as String
    let conditions: String = currentCity["description"] as String
    let country: String = currentCity["country"]! as String
    let address = "\(city), \(country)"
    let cityAnnotation = CityPointAnnotation()

    cityAnnotation.title = address
    cityAnnotation.subtitle = "\(conditions)"
    cityAnnotation.coordinate = location


    self.setRegion(region, animated: true)
    self.addAnnotation(cityAnnotation)
    self.selectAnnotation(cityAnnotation, animated: true)


}

func cityInfoClick(sender:UIButton){
    //sender.performSegueWithIdentifier("segueCityWebView")
}




func mapView(mapView: MKMapView!, viewForAnnotation annotation: MKAnnotation!) -> MKAnnotationView! {
    // Handle any custom annotations.

    if annotation is CityPointAnnotation {

        // Try to dequeue an existing pin view first.
        let reuseId = "CityPointAnnotationView"
        var annotationView = self.dequeueReusableAnnotationViewWithIdentifier(reuseId)
        if annotationView == nil {
            annotationView = MKAnnotationView(annotation: annotation, reuseIdentifier: reuseId)
            annotationView.image = UIImage(named: "marker.png")
            annotationView.rightCalloutAccessoryView = UIButton.buttonWithType(.InfoDark) as UIButton
            annotationView.canShowCallout = true
            return annotationView;

        } else {

            annotationView.annotation = annotation
        }

        return annotationView

    }
    return nil;
}

func mapView(mapView: MKMapView!, didSelectAnnotationView view: MKAnnotationView!) {
    println("didSelectAnnotationView")
}

func mapView(mapView: MKMapView!, annotationView view: MKAnnotationView!, calloutAccessoryControlTapped control: UIControl!) {
    println("calloutAccessoryControlTapped1")

    ///////////////////
    // I want to do a segue here
    // but nothing has the method performSegueWithIdentifier (self, mapView, control....)
    ///////////////////


}


func resetMap(){
    self.removeAnnotations(self.annotations)
    self.removeOverlays(self.overlays)
    var region:MKCoordinateRegion = MKCoordinateRegionMake(self.centerCoordinate, spanQuestion)
    self.setRegion(region, animated: true)
    hasUserCityLocationGuess = false

}
func addRadiusCircle(location: CLLocation){

    var radius = NSUserDefaults.standardUserDefaults().doubleForKey("guess_place_radius") as CLLocationDistance
    var circle = MKCircle(centerCoordinate: location.coordinate, radius: radius )

    self.removeOverlays(self.overlays)
    self.addOverlay(circle)


}

func doGeoCode( cityObject:PFObject ) -> Bool {
    ....
}

func userCityLocationGuess(userGuessTemp:Int)->NSDictionary {
    ....

}
GameMapViewController.swift:

override func viewDidLoad() {
super.viewDidLoad()
....
// Create the game map
gameMap = GameMapViewController(container: mapViewHolder)
mapViewHolder.addSubview(gameMap)

...

}
import UIKit
import MapKit


class GameMapViewController: MKMapView, MKMapViewDelegate{

var spanQuestion:MKCoordinateSpan = MKCoordinateSpanMake(180, 180)
var spanAnswer:MKCoordinateSpan = MKCoordinateSpanMake(180, 180)
var hasUserCityLocationGuess: Bool = false

var containingView: UIView

override init(){
    println ("GameMapViewController init")
    containingView = UIView()
    super.init(frame: CGRect(x: 0, y: 0, width: 1000, height: 1000))

    self.delegate=self
    var latDeltaAnswer:CLLocationDegrees = 50
    var lngDeltaAnswer:CLLocationDegrees = 50
    spanAnswer = MKCoordinateSpanMake(latDeltaAnswer, lngDeltaAnswer)

    var latDeltaQuestion:CLLocationDegrees = 180
    var lngDeltaQuestion:CLLocationDegrees = 180
    spanQuestion = MKCoordinateSpanMake(latDeltaQuestion, lngDeltaQuestion)



}

required init(coder aDecoder: NSCoder) {
    containingView = UIView()
    super.init(coder: aDecoder)
    self.delegate = nil
    println ("GameMapViewController init with decoder")
}


convenience init(container: UIView) {
    println ("GameMapViewController convenience")
    self.init()
    self.delegate = self
    containingView = container


}

func mapViewDidFinishLoadingMap(mapView: MKMapView!) {
    println("mapViewDidFinishLoadingMap")
}

func mapViewWillStartLoadingMap(mapView: MKMapView!) {

    self.frame = CGRect (x: 0, y: 0, width: containingView.frame.width, height: containingView.frame.height)
    self.contentMode = UIViewContentMode.ScaleAspectFill
    superview?.sizeToFit()
    var guessPlaceRecognizer = UILongPressGestureRecognizer(target: self, action: "guessPlace:")
    guessPlaceRecognizer.minimumPressDuration = 1.0
    mapView.addGestureRecognizer(guessPlaceRecognizer)
    mapView.mapType = MKMapType.Satellite

}

func mapView(mapView: MKMapView!, rendererForOverlay overlay: MKOverlay!) -> MKOverlayRenderer! {
    if overlay is MKCircle {
        var circleRenderer = MKCircleRenderer(overlay: overlay)
        circleRenderer.strokeColor = UIColor.redColor()
        circleRenderer.fillColor = UIColor(red: 255, green: 0, blue: 0, alpha: 0.1)
        circleRenderer.lineWidth = 1
        //userOverlayCircleRender = circleRenderer
        return circleRenderer
    } else {
        return nil
    }
}

func guessPlace(gestureRecognizer:UIGestureRecognizer){

    let guessPlaceFirst = NSUserDefaults.standardUserDefaults().boolForKey("guess_place_preference")

    if guessPlaceFirst {
        var touchPoint = gestureRecognizer.locationInView(self)
        var newCoord:CLLocationCoordinate2D = self.convertPoint(touchPoint, toCoordinateFromView: self)
        var userAnnotation = UserPointAnnotation()
        userAnnotation.coordinate = newCoord
        self.addAnnotation(userAnnotation)


        var getLat: CLLocationDegrees = newCoord.latitude
        var getLon: CLLocationDegrees = newCoord.longitude
        var circleCenter: CLLocation =  CLLocation(latitude: getLat, longitude: getLon)
        addRadiusCircle(circleCenter)
        hasUserCityLocationGuess = true
    }

}

func showCity() {
    let location = CLLocationCoordinate2D(latitude: (currentCity["latitude"]! as CLLocationDegrees), longitude: (currentCity["longitude"]! as CLLocationDegrees))
    let region:MKCoordinateRegion = MKCoordinateRegionMake(location, self.spanAnswer)
    let city: String = currentCity["city"]! as String
    let conditions: String = currentCity["description"] as String
    let country: String = currentCity["country"]! as String
    let address = "\(city), \(country)"
    let cityAnnotation = CityPointAnnotation()

    cityAnnotation.title = address
    cityAnnotation.subtitle = "\(conditions)"
    cityAnnotation.coordinate = location


    self.setRegion(region, animated: true)
    self.addAnnotation(cityAnnotation)
    self.selectAnnotation(cityAnnotation, animated: true)


}

func cityInfoClick(sender:UIButton){
    //sender.performSegueWithIdentifier("segueCityWebView")
}




func mapView(mapView: MKMapView!, viewForAnnotation annotation: MKAnnotation!) -> MKAnnotationView! {
    // Handle any custom annotations.

    if annotation is CityPointAnnotation {

        // Try to dequeue an existing pin view first.
        let reuseId = "CityPointAnnotationView"
        var annotationView = self.dequeueReusableAnnotationViewWithIdentifier(reuseId)
        if annotationView == nil {
            annotationView = MKAnnotationView(annotation: annotation, reuseIdentifier: reuseId)
            annotationView.image = UIImage(named: "marker.png")
            annotationView.rightCalloutAccessoryView = UIButton.buttonWithType(.InfoDark) as UIButton
            annotationView.canShowCallout = true
            return annotationView;

        } else {

            annotationView.annotation = annotation
        }

        return annotationView

    }
    return nil;
}

func mapView(mapView: MKMapView!, didSelectAnnotationView view: MKAnnotationView!) {
    println("didSelectAnnotationView")
}

func mapView(mapView: MKMapView!, annotationView view: MKAnnotationView!, calloutAccessoryControlTapped control: UIControl!) {
    println("calloutAccessoryControlTapped1")

    ///////////////////
    // I want to do a segue here
    // but nothing has the method performSegueWithIdentifier (self, mapView, control....)
    ///////////////////


}


func resetMap(){
    self.removeAnnotations(self.annotations)
    self.removeOverlays(self.overlays)
    var region:MKCoordinateRegion = MKCoordinateRegionMake(self.centerCoordinate, spanQuestion)
    self.setRegion(region, animated: true)
    hasUserCityLocationGuess = false

}
func addRadiusCircle(location: CLLocation){

    var radius = NSUserDefaults.standardUserDefaults().doubleForKey("guess_place_radius") as CLLocationDistance
    var circle = MKCircle(centerCoordinate: location.coordinate, radius: radius )

    self.removeOverlays(self.overlays)
    self.addOverlay(circle)


}

func doGeoCode( cityObject:PFObject ) -> Bool {
    ....
}

func userCityLocationGuess(userGuessTemp:Int)->NSDictionary {
    ....

}

}这是因为您混淆了视图和视图控制器。您有一个视图(MKMapView的子类
MKMapView
),但您正在命名它并尝试将其用作控制器。它还执行控制器的工作


所以,你真的应该有一个视图控制器,它拥有并配置一个地图视图(普通的
MKMapView
),然后它可以与segues交互。

是的,我确实把它们弄糊涂了。谢谢你的输入。现在都排序好了。