Перетащите примечание аннотации на карту
Штифт аннотации перетаскивается, но я не мог отбросить его в место назначения. Проблема в том, как я могу получить координату места назначения, где я удаляю пиктограмму аннотации? Существует какой-либо метод?
Изменить 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 out putvalAt всегда один и тот же.
- (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;
}
Ответы
Ответ 1
Сначала вы должны создать пользовательскую аннотацию, подобную этой:
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);
}
}
Ответ 2
Исключительно, реализуйте метод setCoordinates вашей аннотации и сделайте callBAck, когда изменились ваши координаты аннотации.
edit: остерегайтесь свойства dragState вашей аннотации при ее перемещении.
Ответ 3
Разве вы этого не сделаете:
Настройка делегата аннотации,
то
- (void)setCoordinate:(CLLocationCoordinate2D)newCoordinate {
coordinate = newCoordinate;
if (self.delegate respondsToSelector:@selector(mapAnnotationCoordinateHaveChanged))
[self.delegate performSelector(@selector(mapAnnotationCoordinateHaveChanged))];
}
В вашем делегате:
- (void) mapAnnotationCoordinateHaveChanged{
//some coordinates update code
}
Ответ 4
- (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];
}
}
Ответ 5
Пример для Swift 2.2, Xcode 7.3.1:
-
Создание пользовательского класса с использованием протокола MKAnnotation
(примечание: 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)
Здесь вы можете получить новые конечные координаты.
В качестве альтернативы вы можете создать словарь userInfo
для уведомлений свойств пользовательской аннотации coordinate
. Наблюдатели могли затем получить значения после получения уведомления.
Ответ 6
В Swift моя проблема заключалась в том, что атрибут coordinate
был let
в моем подклассе, а не var
, как и в 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()
}
}