[iOS] MapView에 특별한 Annotation 붙이기

보통 PinAnnotationView으로 모양을 많이 내지만 특별하게 사용자 맘대로 그리고 싶을 때 역시 방법이 있더라. 뭐 구조상 당연히 가능하겠지만.

PinAnnotationView는 MKAnnotation을 MapView에 박았을 때 mapView:viewForAnnotation을 통해서 넘겨주는 View의 일종일 뿐이지. 그렇다면 이런 AnnotationView구조를 상속받아서 붙여보면 아마도 될거다.

우선 Annotation 부터
@interface SomeAnnotation : NSObject <MKAnnotation> {
}

@property (nonatomic, readonly) CLLocationCoordinate2D coordinate;

@end

@implementation SomeAnnotation

@synthesize coordinate;

- (id)initWithCoordinate:(CLLocationCoordinate2D) c {
  coordinate = c;
  return self;
}

@end
기냥 뼈대만 뽑아 놨다. 구현 부분은 별 의미가 없을 것 같아서 생략.

AnnotationView쪽도 만들어 줘야겠지.

@interface SomeAnnotationView : MKAnnotationView {
}

@end

@implementation SomeAnnotationView

- (id)initWithAnnotation:(id )annotation
         reuseIdentifier:(NSString *)reuseIdentifier {

  if ((self = [super init])) {
    self.backgroundColor = [UIColor clearColor];
    [self setEnabled:NO]; // not detect touch
  }

  return self;
}

- (void)setAnnotation:(id )annotation {
  super.annotation = annotation;

  if ([annotation isMemberOfClass:[SomeAnnotation class]]) {
    self.frame = CGRectMake(0, 0, WIDTH, HEIGHT);
  }
  else {
    // is need this code? ;;;;
    self.frame = CGRectMake(0, 0, WIDTH, HEIGHT);
  }
}

- (void)drawRect:(CGRect)rect {
  // DRAW IT!
}

@end

drawRect 부분이 역시 핵심이 되겠지 아마. 그냥 보통 UIView의 drawRect 랑 같은 방식으로 화면을 그리면 된다 -_- 나머진 적당히 setAnnotation에서 크기만 잘 잡아주면 되나 보다.

그럼 나머지, 원래 annotation박으려면 상당히 귀찮지만 MKMapViewDelegate 를 상속받아 놓은 쪽에서 mapView:viewForAnnotation 을 만들어 줘야 된다. 이게 모양(뷰)을 넘겨주는 녀석이라서 없으면 보이지도 않아...

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

  if ([annotation isKindOfClass:[SomeAnnotation class]]) {
    SomeAnnotationView *annView = (SomeAnnotationView *)[mapView   

      dequeueReusableAnnotationViewWithIdentifier:   
        @"someannotationview"];

    if (annView == nil) {
      annView = [[[SomeAnnotationView alloc]   
        initWithAnnotation:annotation 
          reuseIdentifier:@"someannotationview"] autorelease];
    }

    annView.annotation = annotation;
    return annView;
  }
  else return nil;
}

특정 identifier일 때 따로 만든 AnnotationView를 넘겨주도록 했다.

그냥 축약한 예제일 뿐. 따라하진 말고 참고만 하자;;

댓글

이 블로그의 인기 게시물

버전(Version)을 제대로 이해하기

소수점 제거 함수 삼총사 ceil(), floor(), round()