Przeciągnij pin adnotacji na widoku mapy

Pin adnotacji jest przeciągalny, ale nie mogłem go upuścić do miejsca docelowego. Problem polega na tym, jak Mogę uzyskać współrzędną lokalizacji docelowej, w której upuszczam pin adnotacji? Istnieją jakieś metody?

Edytuj 1:

Środek pinu adnotacji wydaje się nigdy nie zmieniany tam, gdzie upuszczam pinezkę.

- (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];

}
}

Edytuj 2:

Adnotacja.h

@property (nonatomic,readwrite,assign) CLLocationCoordinate2D coordinate;

Adnotacja.m

- (void)setCoordinate:(CLLocationCoordinate2D)newCoordinate {
coordinate = newCoordinate; 
}

Edit 3: where ever I drag the pin, The NSLog Na zewnątrz jest zawsze tak samo.

- (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);
}
}

Edytuj 4:

Adnotacja.na @ 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; 
}
Author: lu yuan, 2012-05-24

6 answers

Najpierw musisz utworzyć niestandardową adnotację w ten sposób:

Moja uwaga.h

#import <MapKit/MapKit.h>

@interface MyAnnotation : NSObject <MKAnnotation>{

    CLLocationCoordinate2D coordinate;

}
- (id)initWithCoordinate:(CLLocationCoordinate2D)coord;
- (void)setCoordinate:(CLLocationCoordinate2D)newCoordinate;
@end

Moja uwaga.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

Potem wystarczy użyć adnotacji w ten sposób:

// 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];

Musisz również zwrócić widok dla swojej adnotacji. Możesz to zrobić tak:

- (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;
}

Następnie, po przyjęciu protokołu MKMapViewDelegate w kontrolerze, chwytasz współrzędne pinu po przeciągnięciu go w następujący sposób:

- (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);
    }
}
 38
Author: Alladinian,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-05-24 09:49:40

Znienacka zaimplementuj metodę setCoordinates Twojej adnotacji i wykonaj callBAck, gdy zmienią się współrzędne adnotacji

Edit: uważaj na właściwość dragState Twojej adnotacji podczas jej przenoszenia.

 1
Author: CitronEvanescent,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-05-24 08:34:36

Nie chcesz tego robić:

Ustawianie delegata adnotacji, then

- (void)setCoordinate:(CLLocationCoordinate2D)newCoordinate {
   coordinate = newCoordinate; 
   if (self.delegate respondsToSelector:@selector(mapAnnotationCoordinateHaveChanged))
    [self.delegate performSelector(@selector(mapAnnotationCoordinateHaveChanged))];
}

W Twoim delegacie:

- (void) mapAnnotationCoordinateHaveChanged{
 //some coordinates update code
}
 1
Author: CitronEvanescent,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-05-24 10:11:04
- (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];



    }
}
 1
Author: Bhavesh Nayi,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-01-30 12:54:56

Przykład dla Swift 2.2, Xcode 7.3.1:

  • Utwórz własną klasę przyjmującą protokół MKAnnotation

    (Uwaga: Swift nie ma automatycznego powiadamiania o właściwościach zgodnych z KVO, więc dodałem własne-nie jest to wymagane):

    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
        }
    }
    
  • Zadeklaruj widok pin jako przeciągalny:

    // MARK: - MKMapViewDelegate Actions
    func mapView(mapView: MKMapView, viewForAnnotation annotation: MKAnnotation) -> MKAnnotationView? {
    
        let pinView = MKPinAnnotationView(annotation: annotation, reuseIdentifier: pinViewReuseIdentifier)
        pinView.draggable = true
    
        return pinView
    }
    

Teraz, gdy pin jest przeciągany, wywołuje metodę delegata:

func mapView(mapView: MKMapView, didSelectAnnotationView view: MKAnnotationView)

Tutaj możesz odzyskać Nowy koniec współrzędne.


Alternatywnie można utworzyć słownik userInfo dla powiadomień właściwości coordinate adnotacji niestandardowej. Obserwatorzy mogli następnie pobrać wartości po otrzymaniu powiadomienia.

 0
Author: leanne,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-08-08 22:45:44

W Swift moim problemem było to, że coordinate atrybut był let w mojej podklasie, a nie var Jak to jest w 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()
    }
}
 0
Author: Kevin Delord,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-10-13 22:18:28