Как изменить положение кадра для пользовательского MKAnnotationView? - PullRequest
6 голосов
/ 19 марта 2010

Я пытаюсь создать пользовательский вид аннотации путем создания подкласса MKAnnotationView и переопределения метода drawRect. Я хочу, чтобы представление отображалось со смещением относительно позиции аннотации, как это делает MKPinAnnotationView, чтобы точка булавки находилась в указанных координатах, а не в середине булавки. Поэтому я установил положение и размер кадра, как показано ниже. Однако не похоже, что я могу вообще влиять на положение рамки, только на размер. Изображение заканчивается рисованием по центру над позицией аннотации. Любые советы о том, как добиться того, чего я хочу?

MyAnnotationView.h:

@interface MyAnnotationView : MKAnnotationView {

}

MyAnnotationView.m:

- (id)initWithAnnotation:(id <MKAnnotation>)annotation reuseIdentifier:(NSString *)reuseIdentifier {
    if (self = [super initWithAnnotation:annotation reuseIdentifier:reuseIdentifier]) {
        self.canShowCallout = YES;
        self.backgroundColor = [UIColor clearColor];
        // Position the frame so that the bottom of it touches the annotation position 
        self.frame = CGRectMake(0, -16, 32, 32);
    }
    return self;
}

- (void)drawRect:(CGRect)rect {
    [[UIImage imageNamed:@"blue-dot.png"] drawInRect:rect];
}

Ответы [ 4 ]

19 голосов
/ 31 мая 2010

Я попытался использовать centerOffset, и по какой-то причине изображение было в правильном положении при увеличении, но при уменьшении карты изображение отошло бы от того места, где оно должно было быть.Решением этой проблемы была установка рамки изображения со смещением.Вот код, который я использовал (Вы можете пропустить элементы выноски, если у вас нет выноски), я использовал выводы из здесь )

#pragma mark MKMapViewDelegate
- (MKAnnotationView *)mapView:(MKMapView *)aMapView viewForAnnotation:(id <MKAnnotation>)annotation
{
    if(![annotation isKindOfClass:[MyAnnotation class]]) // Don't mess user location
        return nil;

    MKAnnotationView *annotationView = [aMapView dequeueReusableAnnotationViewWithIdentifier:@"spot"];
    if(!annotationView)
    {
        annotationView = [[MKAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:@"spot"];
        annotationView.rightCalloutAccessoryView = [UIButton buttonWithType:UIButtonTypeDetailDisclosure];
        [(UIButton *)annotationView.rightCalloutAccessoryView addTarget:self action:@selector(openSpot:) forControlEvents:UIControlEventTouchUpInside];
        annotationView.enabled = YES;
        annotationView.canShowCallout = YES;
        annotationView.centerOffset = CGPointMake(7,-15);
        annotationView.calloutOffset = CGPointMake(-8,0);
    }

    // Setup annotation view
    annotationView.image = [UIImage imageNamed:@"pinYellow.png"]; // Or whatever

    return annotationView;
}

Настройте centerOffset и calloutOffset какнеобходим для соответствия вашему изображению, желаемой центральной точке и точке выноски.

15 голосов
/ 19 марта 2010

Вместо подкласса MKAnnotationView, вы пытались использовать универсальный MKAnnotationView и устанавливать свойства image и centerOffset?

2 голосов
/ 09 марта 2013

Ваш UIAnnotationView всегда рисуется в одном и том же масштабе, уровень масштабирования карты не имеет значения. Вот почему centerOffset не привязан к уровню масштабирования.

annView.centerOffset это то, что вам нужно. Если вы видите, что ваша булавка находится не в хорошем месте (например, нижний центр немного смещается при изменении уровня масштабирования), это потому, что вы не установили правильный centerOffset.

Кстати, если вы хотите установить точку координаты в нижнем центре изображения, координата x вашего centerOffset должна быть 0,0f, так как annotationView центрирует изображение по умолчанию. Так что попробуйте:

annView.centerOffset = CGPointMake(0, -imageHeight / 2);

Ответ от [ MKAnnotation смещение изображения с пользовательским изображением булавки

0 голосов
/ 04 августа 2011

Спасибо за пример BadPirate.

Я пытался использовать UIImageview, но я не думаю, что это необходимо.

Мой класс выглядел так

@interface ImageAnnotationView : MKAnnotationView {
    UIImageView *_imageView;
    id m_parent;
    BusinessMapAnnotation *m_annotation;

    NSString *stitle;
}

И реализация

- (id)initWithAnnotation:(id <MKAnnotation>)annotation reuseIdentifier:(NSString *)reuseIdentifier
{
    self = [super initWithAnnotation:annotation reuseIdentifier:reuseIdentifier];
    self.frame = CGRectMake(0, 0, kWidth, kHeight);
    self.backgroundColor = [UIColor clearColor];

    self.m_annotation = (BusinessMapAnnotation*)annotation;

    NSString* categoryTitle = m_annotation.sCTitle;

    NSString* l_titleString =  @"NearPin.png";

    if (categoryTitle!= nil ) {
        if ([categoryTitle length] > 0) {
            //NSLog(@"%@", categoryTitle);
            l_titleString = [NSString stringWithFormat:@"Map%@.png", categoryTitle];
            //NSLog(@"%@", l_titleString);
        }
    }

    self.stitle = m_annotation.sTitle;

    _imageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:([stitle isEqualToString:@"You are here"]) ? @"Pushpin_large.png":l_titleString]];
    _imageView.contentMode = UIViewContentModeCenter;

    _imageView.frame = CGRectMake(kBorder, kBorder, kWidth, kHeight);

    [self addSubview:_imageView];
    _imageView.center = ([stitle isEqualToString:@"You are here"]) ? CGPointMake(15.0, -10.0):CGPointMake(kWidth/2, 0.0);

    return self;
}
...