Как изменить положение кадра для настраиваемого MKAnnotationView?

Я пытаюсь создать собственное представление аннотации, создав подкласс 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];
}

person andrei    schedule 19.03.2010    source источник


Ответы (4)


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

person Tom    schedule 19.03.2010
comment
Да, это работает для просмотра аннотаций на основе изображений (чего на самом деле достаточно для моих целей). Но мне все еще интересно узнать об общем случае. - person andrei; 21.03.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 по мере необходимости, чтобы соответствовать вашему изображению, а также желаемую центральную точку и точку выноски.

person BadPirate    schedule 31.05.2010
comment
Вы сказали, что исправление заключается в установке кадра изображения со смещением, но предоставленный код не решает проблему. Вы можете уточнить? centerOffset, похоже, ничего не делает на iOS7 (на iOS6 все было нормально) - person Zoltán Matók; 05.11.2013
comment
Я использую совершенно другую форму для представления аннотации, и, похоже, это не решает проблему. Кроме того, я не думаю, что это решение имеет какое-либо отношение к настройке положения аннотации в соответствии с уровнем масштабирования. - person huong; 20.01.2014
comment
Я тоже это испытал. Мне пришлось установить CenterOffset на 0,0, иначе он переводил изображение вместе с картой, перемещающейся с некоторой функцией отношения смещения x / y. Не знаю почему. - person Timothy Lee Russell; 31.05.2015

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

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

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

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

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

person VICTORGS3    schedule 09.03.2013
comment
да, я понял это из этого ответа, я буду ссылаться на него в своем посте :) - person VICTORGS3; 28.04.2015

Спасибо за пример 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;
}
person NBALA    schedule 04.08.2011