在MKMapView上旋转注释图像

时间:2014-07-27 00:36:10

标签: ios uiimageview uiimage mkmapview mkannotationview

我正在尝试将添加到MKMapView的图像旋转为注释。

这是代码:

-(MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:   (id<MKAnnotation>)annotation
{
  if (! [annotation isKindOfClass:[IGAMapAnnotation class]])
  {
    //return default view if annotation is NOT of type IGAMapAnnotation...
    return nil;
  }


  MKAnnotationView *annotationView = [mapView dequeueReusableAnnotationViewWithIdentifier:@"IGAMapAnnotation"];

  if (annotationView == nil)
  {
    annotationView = [[MKAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:@"IGAMapAnnotation"];

    annotationView.enabled = YES;
    annotationView.canShowCallout = YES;
    annotationView.rightCalloutAccessoryView = [UIButton buttonWithType:UIButtonTypeDetailDisclosure];
  }
  else
  {
    annotationView.annotation = annotation;
  }

  IGAMapAnnotation *myLocation = (IGAMapAnnotation *) annotation;

  // THIS IS IT!
  if ([myLocation.type isEqual: @"PLANE"]) {
    UIImage *planeImage = [UIImage imageNamed:@"planetracked.png"];

    UIImageView *planeImageView = [[UIImageView alloc]initWithImage:planeImage];
    planeImageView.transform = CGAffineTransformMakeRotation(M_PI_2);

    annotationView.image = planeImageView;
  }

  return annotationView;
}

它显然给了我一个错误,因为annotationView.image应该分配一个图像而不是UIImageView。我尝试过各种旋转图像的方法,例如:

- (UIImage *)rotateImage:(UIImage *)image onDegrees:(NSString *)heading {

  double angle = [heading doubleValue];

  CGSize s = {image.size.width, image.size.height};
  UIGraphicsBeginImageContext(s);
  CGContextRef ctx = UIGraphicsGetCurrentContext();
  CGContextTranslateCTM(ctx, 0,image.size.height);
  CGContextScaleCTM(ctx, 1.0, -1.0);

  CGContextRotateCTM(ctx, 2*M_PI*angle/360);
  CGContextDrawImage(ctx,CGRectMake(0,0,image.size.width, image.size.height),image.CGImage);
  UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
  UIGraphicsEndImageContext();
  return newImage;
}

它们也不起作用 - 地图上没有图像。

任何人都知道如何在MKMapView上旋转注释图像?

百万,谢谢!

2 个答案:

答案 0 :(得分:4)

而不是:

annotationView.image = planeImageView;

这绝对是错误的(image属性是UIImageplaneImageViewUIImageView),使用addSubview:添加UIImageView }到注释视图(保留视图的image属性nil并且未使用)。

但是,您还需要进行一些其他调整,以便:

  • 图像完全以坐标(而不是角落)为中心,并且
  • 点击图片上的任意位置会显示标注(而不是只有一个特定的角落)

要做这些事情,请增加两个视图的帧大小以考虑旋转可能的最大宽度(假设图像是正方形,这是原始宽度的2倍的平方根)并设置图像视图&#39 ; s contentMode到&#34;中心&#34;因此,图像不会因这些帧大小的变化而失真。

另一个重要问题是,如果你IGAMapAnnotation的{​​{1}}不是&#34;飞机&#34;,那么它们将是:

  • 如果创建了 new 注释视图,则不可见(因为未设置type,也未将任何子视图添加到注释视图中),或者,
  • 展示&#34;飞机&#34;带有一些其他注释标题的图像,因为注释视图已出列(并且正在重新用于另一个注释)。

为了避免两种类型的注释(&#34;平面&#34; /&#34;而不是平面&#34;)重复使用彼此的视图,我建议使用不同的重复使用每个类型的标识符每个注释)并对视图应用特定于类型的更改。

修订后的image方法如下所示:

viewForAnnotation

顺便说一下,使用-(MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id<MKAnnotation>)annotation { if (! [annotation isKindOfClass:[IGAMapAnnotation class]]) { //return default view if annotation is NOT of type IGAMapAnnotation... return nil; } IGAMapAnnotation *myLocation = (IGAMapAnnotation *)annotation; BOOL typeIsPlane = [myLocation.type isEqualToString:@"PLANE"]; int planeImageViewTag = 42; NSString *reuseId = typeIsPlane ? @"IGAMapAnnotationPlane" : @"IGAMapAnnotationOther"; MKAnnotationView *annotationView = [mapView dequeueReusableAnnotationViewWithIdentifier:reuseId]; if (annotationView == nil) { annotationView = [[MKAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:reuseId]; annotationView.enabled = YES; annotationView.canShowCallout = YES; annotationView.rightCalloutAccessoryView = [UIButton buttonWithType:UIButtonTypeDetailDisclosure]; if (typeIsPlane) { //Here, just add the image view to the annotation view with no //rotation. Only want to add the image view to the annotation //view ONCE when the annotation view is initially created. If //view is dequeued, it will already have an image view and we //just update its rotation. UIImage *planeImage = [UIImage imageNamed:@"planetracked.png"]; UIImageView *planeImageView = [[UIImageView alloc] initWithImage:planeImage]; planeImageView.tag = planeImageViewTag; planeImageView.contentMode = UIViewContentModeCenter; [annotationView addSubview: planeImageView]; CGRect avFrame = annotationView.frame; //"1.5" on next line is the square root of 2 rounded up a bit. avFrame.size = CGSizeMake(planeImage.size.width*1.5, planeImage.size.height*1.5); annotationView.frame = avFrame; planeImageView.frame = annotationView.frame; } else { //If this IGAMapAnnotation is not a "plane", //show some other default image. //(Or, you could return nil to show a default red pin.) annotationView.image = [UIImage imageNamed:@"NotAPlane.png"]; //May or may not need to set centerOffset. //Either remove or adjust 0,0 as needed to //center the image on the coordinates. annotationView.centerOffset = CGPointMake(0, 0); } } else { annotationView.annotation = annotation; } //At this point, we have a new or dequeued annotation view ready //and pointing to the current annotation. //Now make any annotation-specific changes to the view... if (typeIsPlane) { UIImageView *planeImageView = (UIImageView *)[annotationView viewWithTag:planeImageViewTag]; planeImageView.transform = CGAffineTransformMakeRotation(M_PI_2); //Replace M_PI_2 with rotation specific to this annotation's heading. } return annotationView; } 代替isEqualToString:isEqual: s。

<小时/> 对于NSString问题,removeAnnotations:必须包含地图上注释的实例。要删除现有注释,您必须提供对最初添加的完全相同对象的引用。

如果您要始终删除所有注释并重新添加所有注释,则可以执行mapLocations

如果您只删除某些注释,则需要保留对最初添加的注释的引用,或者遍历地图视图的[self.mapView removeAnnotations:self.mapView.annotations];数组并识别哪些应删除(保留一个临时annotations作为&#34;注释列表以删除&#34;)然后使用该注释列表调用NSMutableArray以删除。

答案 1 :(得分:1)

以下似乎有效。百万感谢安娜没有他们不会拥有的人!

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

  if (! [annotation isKindOfClass:[IGAMapAnnotation class]]) {
    return nil;
  }

  IGAMapAnnotation *myLocation = (IGAMapAnnotation *) annotation;

BOOL typeIsPlane = [myLocation.navaidType isEqualToString:@"PLANE"];
BOOL typeIsOne  = [myLocation.navaidType isEqualToString:@"ONE"];
BOOL typeIsTwo = [myLocation.navaidType isEqualToString:@"TWO"];
BOOL typeIsThree = [myLocation.navaidType isEqualToString:@"THREE"];

int planeImageViewTag = 42;

NSString *reuseId;
if (typeIsPlane)
    reuseId = @"IGAMapAnnotationPlane";

else if (typeIsOne)
    reuseId = @"IGAMapAnnotationOne";

else if (typeIsTwo)
    reuseId = @"IGAMapAnnotationTwo";

else if (typeIsThree)
    reuseId = @"IGAMapAnnotationThree";

else
    reuseId = @"IGAMapAnnotationOther";

MKAnnotationView *annotationView = [mapView dequeueReusableAnnotationViewWithIdentifier:reuseId];

if (annotationView == nil)
{
    annotationView = [[MKAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:reuseId];
    annotationView.enabled = YES;
    annotationView.canShowCallout = YES;
    annotationView.rightCalloutAccessoryView = [UIButton buttonWithType:UIButtonTypeDetailDisclosure];

    if (typeIsPlane)
    {

        UIImage *planeImage = [UIImage imageNamed:@"mapPLANE.png"];

        UIImageView *planeImageView = [[UIImageView alloc] initWithImage:planeImage];
        planeImageView.tag = planeImageViewTag;
        planeImageView.contentMode = UIViewContentModeCenter;

        [annotationView addSubview: planeImageView];

        CGRect avFrame = annotationView.frame;
        //"1.5" on next line is the square root of 2 rounded up a bit.
        avFrame.size = CGSizeMake(planeImage.size.width*1.5,
                                  planeImage.size.height*1.5);
        annotationView.frame = avFrame;
        planeImageView.frame = annotationView.frame;
    }

    else if (typeIsOne)
    {
        annotationView.image = [UIImage imageNamed:@"one.png"];
        annotationView.centerOffset = CGPointMake(0, 0);
    }

    else if (typeIsTwo)
    {
        annotationView.image = [UIImage imageNamed:@"two.png"];
        annotationView.centerOffset = CGPointMake(0, 0);
    }

    else if (typeIsThree)
    {
        annotationView.image = [UIImage imageNamed:@"three.png"];
        annotationView.centerOffset = CGPointMake(0, 0);
    }

    else
        return nil;
}

else
{
    annotationView.annotation = annotation;
}

if (typeIsPlane)
{
    // Convert current heading string to double
    double headingDouble = [currentHeading doubleValue];

    UIImageView *planeImageView = (UIImageView *)[annotationView viewWithTag:planeImageViewTag];
    planeImageView.transform = CGAffineTransformMakeRotation(DEGREES_TO_RADIANS(headingDouble));
}

return annotationView;

}