2014-07-27 6 views
2

MKMapView에 추가 된 이미지를 주석으로 회전하려고합니다. 그것은 분명 나에게있는 UIImageView를 이미지를 할당하고 안 annotationView.image 같은 오류를 제공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; 
} 

:

는 코드입니다. 나는 단지 이미지를 회전시키는 다양한 방법을 시도했다. 예를 들면 다음과 같다 :

- (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에서 주석 이미지를 회전하는 방법을 알고 있습니까?

백만 감사드립니다!

+0

'annotationView.image = planeImageView; 대신 틀린 것은'[annotationView addSubview : planeImageView];'를 시도해보십시오. 또한'type'이 "PLANE"이 아닌 경우 이미지가 설정되지 않기 때문에 주석이 보이지 않을 것입니다. 그래서'else' 부분을 추가해야합니다. – Anna

+0

안나. 정말 고맙습니다. 그것은 트릭을합니다. 이미지가 회전됩니다. 이제 문제는 주석이 업데이트 될 때 맵에서 제거하는 것입니다 (제 경우에는 5 초마다 업데이트됩니다). 나는 이것을 사용하고있다 :'[self.mapView removeAnnotations : mapLocations];'그러나 이미지는 제거되지 않는다. 게다가 좌표가 바뀌지 않았지만 맵의 다른 위치에 나타날 수 있다는 것을 알았습니다. 이유가 궁금합니다. 정말 고맙습니다! –

답변

4

대신에 : 확실히 잘못

annotationView.image = planeImageView; 

, 뷰의 image 속성을 떠나 (주석보기에 UIImageView을 추가 addSubview:를 사용합니다 (image 속성 planeImageViewUIImageViewUIImage 동안이다) nil 및 미사용). 있도록

그러나, 당신은 또한 다른 조정을해야합니다 :

  • 이미지가 정확히 중심으로하는 (대신 코너) 좌표와
  • 이미지의 아무 곳이나 누르면 가져온다

이러한 작업을 수행하려면 두 뷰의 프레임 크기를 회전에서 가능한 최대 너비 (원의 2 배의 제곱근)를 고려하여 늘립니다. 너비 가정 이미지가 사각형입니다) 이미지 뷰의 contentMode을 "가운데"로 설정하면 이러한 프레임 크기가 변경 되어도 이미지가 왜곡되지 않습니다.

다른 큰 문제는 당신이 IGAMapAnnotation의이있는 경우 그 type는 "비행기가"아니라고, 그들은 것 중 하나를하십시오 새로운 주석 뷰가 생성 된 경우

  • 이 보이지 않는이 (image 때문에 설정되지 않은 또는
  • 기타 주석이있는 "평면"이미지가 표시됩니다 (주석보기가 대기열에서 제외 되었기 때문에 (다른 주석에 대해 다시 사용됨).

는 I 각 (하지 각각에 대한 상이한 재사용 식별자를 이용하여 제안의 서로 다른 뷰를 다시 사용하는 ("평면"/ "없는 평면을") 주석의 두 가지 유형을 방지하려면 주석)을 적용하고 유형별 변경 사항을보기에 적용합니다., 그런데

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

NSString들과 isEqualToString: 대신 isEqual:를 사용

개정 viewForAnnotation 방법은 다음과 같을 것입니다. removeAnnotations: 문제에 대한


, 그것은 mapLocations지도에 주석의 새로운 인스턴스를 포함해야합니다. 기존 주석을 제거하려면 원래 추가 된 동일한 객체에 대한 참조를 제공해야합니다.

항상 모든 주석을 제거하고 모든 주석을 다시 추가하는 경우, 당신은 단지 [self.mapView removeAnnotations:self.mapView.annotations]; 할 수 있습니다.

일부 주석을 제거 할 경우에는 원래 추가 된 것들에 대한 참조를 유지하거나지도보기의 annotations 배열을 반복하고 목록으로 임시 NSMutableArray을 유지 (사람이 삭제되어야 식별해야합니다 "제거 할 주석") 제거 할 주석 목록으로 removeAnnotations:을 호출하십시오.

+0

안나. 다시 한번 감사드립니다! 이것은 위대합니다. 그래서 typeIsPlane과 비슷한 이미지 유형을 몇 가지 추가했습니다. 또한 ViewWillAppear에 다음 코드를 추가하고 평면 좌표를 매 5 초마다 가져 와서 맵에 이미지를 그립니다. 마지막으로 문제는 다른 유형의 이미지 (비행기 제외)가지도가 업데이트 될 때마다 계속 회전하여 잘못된 이미지를 넣을 때마다 계속 발생한다는 것입니다. (NSMutableArray alloc) init]; ' '[self addAnnotation] . 신비! :-) 많은 감사합니다! –

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; 

} 
+0

** currentHeading ** 값을 어떻게 적용 할 수 있는지 보여 줄 수 있습니까? –