2014-03-25 17 views
2

我已阅读了很多关于MKAnnotation以及您需要如何在您的子类中实现setCoordinate以及draggable=TRUE以便使整个shebang可拖动。MKAnnotation需要长时间点击拖动之前​​的单击tap

我的情况是,在我的iOS7专用应用程序中,无论我是否实施setCoordinate,我的注释都是可拖动的......但问题是我需要先点击它(弹出标注附件)然后很长点击它,然后才会悬停在地图上方的空中,并可以拖动。这会让用户感到困惑,因为它与标准地图应用程序中的方式不同。请注意,在地图应用程序中,如果不进行先决条件点按操作,则长按一个注释会使其悬停在可拖动的位置&。

我试过执行setCoordinate,但这没有什么区别。除此之外,我的注记子类只存储经度为&的经度,这很好。我只是希望它能够在长时间内立即拖动。

我的View Controller的相关代码实现MKMapViewDelegate。我可以通过在委托方法中放置断点来验证这一点。

- (void)viewDidLoad 
{ 
     [super viewDidLoad]; 
[mapView setDelegate:self];  
} 

-(MKAnnotationView *)mapView:(MKMapView *)mV viewForAnnotation: 
(id <MKAnnotation>)annotation { 

    MKPinAnnotationView *pinView = nil; 
    if(annotation != mapView.userLocation) 
    { 
     static NSString *defaultPinID = @"pointPin"; 
     pinView = (MKPinAnnotationView *)[mapView dequeueReusableAnnotationViewWithIdentifier:defaultPinID]; 
     if (pinView == nil) { 
      pinView = [[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:defaultPinID]; 
     } 
     pinView.pinColor = MKPinAnnotationColorRed; 
     if ([annotation isKindOfClass:[SimpleMapAnnotation class]]) { 
      SimpleMapAnnotation *simpleMapAnnotation = (SimpleMapAnnotation*)annotation; 
      if ([simpleMapAnnotation color]) { 
       pinView.pinColor = [simpleMapAnnotation color]; 
      } 
      if (simpleMapAnnotation.moveable) { 
       pinView.draggable=TRUE; 
       // delete button to remove an annotation 
       UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom]; 
       [button setImage:[[UIImage alloc] initWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"trash" ofType:@"png"]] forState:UIControlStateNormal] ; 
       button.frame = CGRectMake(0, 0, 23, 23); 
       pinView.rightCalloutAccessoryView = button; 
      } 
     } 
     pinView.canShowCallout = YES; 
     pinView.animatesDrop = YES; 
    } 
    else { 
     [mapView.userLocation setTitle:@"I am here"]; 
    } 
    return pinView; 
} 

- (void)mapView:(MKMapView *)theMapView annotationView:(MKAnnotationView *)view 
calloutAccessoryControlTapped:(UIControl *)control{ 
    if([view.annotation isKindOfClass:[SimpleMapAnnotation class]]){ 
     SimpleMapAnnotation *annotation = (SimpleMapAnnotation*)view.annotation; 

     //remove the point from the database 
    //<snip> 

     [UIView animateWithDuration:0.3 delay:0.0 options:0 animations:(void (^)(void)) ^{ 
      //remove the annotation from the map 
      view.alpha = 0.0f; 
     } 
         completion:^(BOOL finished){ 
          [theMapView removeAnnotation:annotation]; 
          view.alpha=1.0f; 
         }]; 

    } 
} 


- (void)mapView:(MKMapView *)mapView 
annotationView:(MKAnnotationView *)annotationView 
didChangeDragState:(MKAnnotationViewDragState)newState 
    fromOldState:(MKAnnotationViewDragState)oldState 
{ 
    if (newState == MKAnnotationViewDragStateEnding) 
    { 
     if ([annotationView.annotation isMemberOfClass:[SimpleMapAnnotation class]]) { 
      SimpleMapAnnotation *simpleMapAnnotation = (SimpleMapAnnotation*)annotationView.annotation; 
      simpleMapAnnotation.latitude = [NSNumber numberWithDouble:simpleMapAnnotation.coordinate.latitude]; 
      simpleMapAnnotation.longitude = [NSNumber numberWithDouble:simpleMapAnnotation.coordinate.longitude]; 
     } 
     CLLocationCoordinate2D droppedAt = annotationView.annotation.coordinate; 
     NSLog(@"dropped at %f,%f", droppedAt.latitude, droppedAt.longitude); 
    } 
} 

回答

0

我最终使用的是this solution,它不仅在长时间拖动之前摆脱了第一次敲击的需要,而且拖动时用户感觉非常平滑,并且具有大的可拖动区域。 Azavea在他们的博客here上实施了一些解释。

我的应用程序的下一个版本几乎完成了(着名的遗言),它使用了上述的稍微修改过的版本,即它(a)像原始一样拖动,(b)允许可点击动作(c)特别忽略了注释的长时间使用,因此当试图拖动时,不会因不需要的轻击操作而感到恼火。一旦我完成,我打算分叉或分支(我对你在这种情况下做了些什么)上面的github项目来添加这个功能。如果我真的很幸运,我还希望能够修复或至少配置他们在链接到的博客的第二段中提到的快速刷卡问题。

5

要开始拖动MKAnnotationView对象,应首先选择它。这是设计。

如果您想立即开始移动注释视图,您应该在将长按键的触摸传送到对象之前将selected属性设置为YES

为此做出MKPinAnnotationView类的继任者如下:

-(MKAnnotationView *)mapView:(MKMapView *)mV viewForAnnotation:(id <MKAnnotation>)annotation { 
    ... 

    if (pinView == nil) { 
     pinView = [[MKImmideateDragPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:defaultPinID]; 
    } 

    ... 

} 

你的脚将开始拖累:

// MKImmideateDragPinAnnotationView.h 
@interface MKImmideateDragPinAnnotationView : MKPinAnnotationView 
@end 


// MKImmideateDragPinAnnotationView.m 
@implementation MKImmideateDragPinAnnotationView 

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event 
{ 
    [self setSelected:YES]; 
    [super touchesBegan:touches withEvent:event]; 
} 

@end 

在你的代码更改MKPinAnnotationViewMKImmideateDragPinAnnotationView类在pinView分配立即长时间点击。和往常一样,将在单击上显示标注。

这个技巧可以在iOS 6.xx - iOS 7.xx中的任何MKAnnotationView类中使用。

+0

我真的必须为响应的巨大延迟而道歉,伊凡 - 我在几个星期之内离开了,在这期间我发现了一个实际上是解决方案的github项目,并且我即将发布这个答案作为答案。还有关于第三方代码的其他内容适合我需要的内容,当我从假期回来时,我立即忘记回复您的答案。尽管如此,尽管我没有尝试过您的解决方案,但它确实看起来很有前景,并且在类似的情况下对其他人也有帮助。干杯。 – bobsmells

+0

嘿,没问题。您提到的解决方案也很有趣,它使我成为相当不错的WhirlyGlobe框架。更多的解决方案更多的可能 – IvanRublev