在地图视图上拖动注释引脚
注释引脚是可拖动的,但我不能将其拖放到目标位置。 问题是我怎么能得到目标位置的坐标,我放弃注释引脚? 任何方法存在?
编辑1:
注释引脚的中心似乎从来没有改变,我放弃任何地方的引脚。
- (void)mapView:(MKMapView *)mapView annotationView:(MKAnnotationView *)annotationView didChangeDragState:(MKAnnotationViewDragState)newState fromOldState:(MKAnnotationViewDragState)oldState { if (newState == MKAnnotationViewDragStateEnding) { NSLog(@"x is %f", annotationView.center.x); NSLog(@"y is %f", annotationView.center.y); CGPoint dropPoint = CGPointMake(annotationView.center.x, annotationView.center.y); CLLocationCoordinate2D newCoordinate = [self.mapView convertPoint:dropPoint toCoordinateFromView:annotationView.superview]; [annotationView.annotation setCoordinate:newCoordinate]; } }
编辑2:
Annotation.h
@property (nonatomic,readwrite,assign) CLLocationCoordinate2D coordinate;
Annotation.m
- (void)setCoordinate:(CLLocationCoordinate2D)newCoordinate { coordinate = newCoordinate; }
编辑3:在哪里我拖动的引脚,NSLog出放弃的总是相同的。
- (void)mapView:(MKMapView *)mapView annotationView:(MKAnnotationView *)annotationView didChangeDragState:(MKAnnotationViewDragState)newState fromOldState:(MKAnnotationViewDragState)oldState { if (newState == MKAnnotationViewDragStateEnding) { CLLocationCoordinate2D droppedAt = annotationView.annotation.coordinate; NSLog(@"Pin dropped at %f,%f", droppedAt.latitude, droppedAt.longitude); } }
编辑4:
Annotaion.m @dynamic startAddr;
- (CLLocationCoordinate2D)coordinate { coordinate.latitude = [self.startAddr.latitude doubleValue]; coordinate.longitude = [self.startAddr.longitude doubleValue]; return coordinate; } - (void)setCoordinate:(CLLocationCoordinate2D)newCoordinate { //I need to update the self.startAddr.latitude and longitude here. Problem solved. self.startAddr.latitude = [NSNumber numberWithDouble:newCoordinate.latitude]; self.startAddr.longitude = [NSNumber numberWithDouble:newCoordinate.longitude]; coordinate = newCoordinate; }
首先你必须像这样创build一个自定义注释:
MyAnnotation.h
#import <MapKit/MapKit.h> @interface MyAnnotation : NSObject <MKAnnotation>{ CLLocationCoordinate2D coordinate; } - (id)initWithCoordinate:(CLLocationCoordinate2D)coord; - (void)setCoordinate:(CLLocationCoordinate2D)newCoordinate; @end
MyAnnotation.m
#import "MyAnnotation.h" @implementation MyAnnotation @synthesize coordinate; - (NSString *)subtitle{ return nil; } - (NSString *)title{ return nil; } -(id)initWithCoordinate:(CLLocationCoordinate2D)coord { coordinate=coord; return self; } -(CLLocationCoordinate2D)coord { return coordinate; } - (void)setCoordinate:(CLLocationCoordinate2D)newCoordinate { coordinate = newCoordinate; } @end
之后,你只需要像这样使用你的注释:
// Assuming you have imported MyAnnotation.h and you have a self.map property pointing to a MKMapView MyAnnotation *myPin = [[MyAnnotation alloc] initWithCoordinate:self.map.centerCoordinate]; // Or whatever coordinates... [self.map addAnnotation:myPin];
另外,您必须返回一个视图来查看注释。 你可以这样做:
- (MKAnnotationView *) mapView: (MKMapView *) mapView viewForAnnotation: (id<MKAnnotation>) annotation { MKPinAnnotationView *pin = (MKPinAnnotationView *) [self.map dequeueReusableAnnotationViewWithIdentifier: @"myPin"]; if (pin == nil) { pin = [[[MKPinAnnotationView alloc] initWithAnnotation: annotation reuseIdentifier: @"myPin"] autorelease]; // If you use ARC, take out 'autorelease' } else { pin.annotation = annotation; } pin.animatesDrop = YES; pin.draggable = YES; return pin; }
然后,一旦你在你的控制器中采用了MKMapViewDelegate
协议,你可以像下面这样拖动它来获取一个引脚的坐标:
- (void)mapView:(MKMapView *)mapView annotationView:(MKAnnotationView *)annotationView didChangeDragState:(MKAnnotationViewDragState)newState fromOldState:(MKAnnotationViewDragState)oldState { if (newState == MKAnnotationViewDragStateEnding) { CLLocationCoordinate2D droppedAt = annotationView.annotation.coordinate; NSLog(@"Pin dropped at %f,%f", droppedAt.latitude, droppedAt.longitude); } }
突然间,实现注释的setCoordinates方法,并在注释坐标发生变化时进行callBAck
编辑:当它的移动时注意你的注释的dragState属性。
你不想这样做:
然后设置注释代理
- (void)setCoordinate:(CLLocationCoordinate2D)newCoordinate { coordinate = newCoordinate; if (self.delegate respondsToSelector:@selector(mapAnnotationCoordinateHaveChanged)) [self.delegate performSelector(@selector(mapAnnotationCoordinateHaveChanged))]; }
在你的代表中:
- (void) mapAnnotationCoordinateHaveChanged{ //some coordinates update code }
- (MKAnnotationView *) mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>) annotation { MKAnnotationView *a = [ [ MKAnnotationView alloc ] initWithAnnotation:annotation reuseIdentifier:@"currentloc"]; // a.title = @"test"; if ( a == nil ) a = [ [ MKAnnotationView alloc ] initWithAnnotation:annotation reuseIdentifier: @"currentloc" ]; NSLog(@"%f",a.annotation.coordinate.latitude); NSLog(@"%f",a.annotation.coordinate.longitude); CLLocation* currentLocationMap = [[[CLLocation alloc] initWithLatitude:a.annotation.coordinate.latitude longitude:a.annotation.coordinate.longitude] autorelease]; [self coordinatesToDMS:currentLocationMap]; MKPinAnnotationView *annView=[[MKPinAnnotationView alloc] initWithAnnotation:a reuseIdentifier:@"currentloc"]; if(a.annotation.coordinate.longitude == mapView.userLocation.coordinate.longitude || a.annotation.coordinate.latitude == mapView.userLocation.coordinate.latitude ) { if ([annotation isKindOfClass:MKUserLocation.class]) { //user location view is being requested, //return nil so it uses the default which is a blue dot... return nil; } //a.image = [UIImage imageNamed:@"userlocation.png"]; //a.pinColor=[UIColor redColor]; } else { // annView.image =[UIImage imageNamed:@"map-pin.png"]; //PinFirst=FALSE; //annView.pinColor = [UIColor redColor]; // annView.annotation=annotation; } annView.animatesDrop = YES; annView.draggable = YES; annView.canShowCallout = YES; return annView; } - (void)mapView:(MKMapView *)mapView regionDidChangeAnimated:(BOOL)animated { NSLog(@"map Drag"); } - (void)mapView:(MKMapView *)mapView annotationView:(MKAnnotationView *)view didChangeDragState:(MKAnnotationViewDragState)newState fromOldState:(MKAnnotationViewDragState)oldState; { NSLog(@"pin Drag"); if (newState == MKAnnotationViewDragStateEnding) { CLLocationCoordinate2D droppedAt = view.annotation.coordinate; NSLog(@"Pin dropped at %f,%f", droppedAt.latitude, droppedAt.longitude); CLLocation* draglocation = [[[CLLocation alloc] initWithLatitude:droppedAt.latitude longitude:droppedAt.longitude] autorelease]; } }
Swift 2.2,Xcode 7.3.1的例子:
-
使用MKAnnotation协议创build自定义类
(注:Swift没有自动通知KVO兼容的属性,所以我已经添加了我自己的 – 这不是必需的):
import MapKit class MyAnnotation: NSObject, MKAnnotation { // MARK: - Required KVO-compliant Property var coordinate: CLLocationCoordinate2D { willSet(newCoordinate) { let notification = NSNotification(name: "VTAnnotationWillSet", object: nil) NSNotificationCenter.defaultCenter().postNotification(notification) } didSet { let notification = NSNotification(name: "VTAnnotationDidSet", object: nil) NSNotificationCenter.defaultCenter().postNotification(notification) } } // MARK: - Required Initializer init(coordinate: CLLocationCoordinate2D) { self.coordinate = coordinate } }
-
将引脚视图声明为可拖动:
// MARK: - MKMapViewDelegate Actions func mapView(mapView: MKMapView, viewForAnnotation annotation: MKAnnotation) -> MKAnnotationView? { let pinView = MKPinAnnotationView(annotation: annotation, reuseIdentifier: pinViewReuseIdentifier) pinView.draggable = true return pinView }
现在,当该引脚被拖动时,它调用委托方法:
func mapView(mapView: MKMapView, didSelectAnnotationView view: MKAnnotationView)
在这里,您可以检索新的结束坐标。
或者,您可以为自定义注释的coordinate
属性的通知创build一个userInfo
字典。 观察者可以在收到通知后检索这些值。
在Swift中,我的问题是coordinate
属性是我的子类中的一个let
,而不是像MKAnnotation
中的MKAnnotation
。
class MyAnnotation : NSObject, MKAnnotation { let title : String? let subtitle : String? var coordinate : CLLocationCoordinate2D init(title: String, subtitle: String, coordinate: CLLocationCoordinate2D) { self.title = title self.subtitle = subtitle self.coordinate = coordinate super.init() } }