【问题标题】:How do I change the frame position for a custom MKAnnotationView?如何更改自定义 MKAnnotationView 的框架位置?
【发布时间】:2010-03-19 17:13:23
【问题描述】:

我正在尝试通过子类化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];
}

【问题讨论】:

    标签: iphone mapkit mkannotation


    【解决方案1】:

    我尝试使用 centerOffset,但由于某种原因,图像在放大时处于正确的位置,但是当您将地图缩小时,图像会远离它应该在的位置。对此的解决方法是使用偏移量设置图像帧。这是我使用的代码(如果没有标注,可以省略标注的内容),我使用了来自here 的引脚)

    #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 以适合您的图像、所需的中心点和标注点。

    【讨论】:

    • 您说“解决此问题的方法是使用偏移量设置图像帧”,但提供的代码并不能解决问题。你能详细说明吗? centerOffset 在 iOS7 上似乎没有做任何事情(在 iOS6 上很好)
    • 我在注释视图中使用了完全不同的形状,这似乎无法解决问题。另外,我认为这个解决方案与根据缩放级别调整注释的位置没有任何关系。
    • 我也经历过。我必须将 CenterOffset 设置为 0,0,否则它会将图像与地图一起以偏移 x/y 比率的某个函数移动。不知道为什么。
    【解决方案2】:

    您是否尝试过使用通用 MKAnnotationView 并设置 imagecenterOffset 属性,而不是子类 MKAnnotationView?

    【讨论】:

    • 是的,这适用于基于图像的注释视图(这实际上对我的目的来说已经足够了)。但我仍然对一般情况感到好奇。
    【解决方案3】:

    您的UIAnnotationView 始终以相同的比例绘制,地图的缩放级别无关紧要。这就是centerOffset 不受缩放级别约束的原因。

    annView.centerOffset 是您所需要的。如果您发现您的图钉位置不对(例如更改缩放级别时底部中心移动了一点),那是因为您没有设置正确的centerOffset

    顺便说一句,如果你想将坐标点设置在图像的底部中心,你的centerOffset的x坐标应该是0.0f,因为annotationView默认居中图像。所以试试吧:

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

    来自[MKAnnotation image offset with custom pin image的回答

    【讨论】:

    • 是的,我是从那个答案中得到的,我会在我的帖子中链接它:)
    【解决方案4】:

    感谢 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;
    }
    

    【讨论】:

      猜你喜欢
      • 2011-10-23
      • 2012-11-30
      • 1970-01-01
      • 2011-09-17
      • 2012-05-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多