swift自定义地图类

时间:2015-01-14 19:04:52

标签: ios swift mapkit segue

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

我创建了一个类:

class GameMapViewController: MKMapView, MKMapViewDelegate{...}

我在主视图控制器的代码中启动类(并将其作为子视图添加到故事板上的视图,以便我可以更轻松地控制它的位置):

gameMap = GameMapViewController(container: mapViewHolder)

将一切设置为正常,除了我想从自定义注释触发segue时,所有工作都有效:

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

当我点击注释标注时会调用didSelectAnnotationView,但我找不到任何方法performSegueWithIdentifier,所有solutionssimilar的问题都会显示我应该用....

(我已经尝试将MapKit View放到故事板上并将其类更改为使用GameMapViewController但是没有一个init函数被触发)

我猜它是如何初始化我的自定义类的?

MainViewController.swift:

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

...

}

GameMapViewController.swift:

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 {
    ....

}

}

1 个答案:

答案 0 :(得分:2)

这是因为您混淆了视图和查看控制器。你有一个视图(MKMapView的子类,但你正在命名它并尝试将它用作控制器。它也是控制器的工作。

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