调整MKAnnotationView图像大小当地图放大和缩小?

我拥有的

我在地图上有大约150个MKAnnotationView。 每个MKAnnotationView都有一个替代默认引脚的图像。

现在发生了什么

当地图放大时,MKAnnotationViews变小,反之缩小。

我希望发生的事情

那么我希望它是另一种方式。 因为当地图很小的时候,我希望MKAnnotationViews会更小,所以用户可以看到他们,而当他放大的时候,我希望他们会更大。

到目前为止,我有什么代码

我知道如何获得缩放变化,我知道我可以得到“pMapView.region.span.latitudeDelta”作为缩放量的参考。 我知道我可以改变annotationView.frame。

-(void)mapView:(MKMapView *)pMapView regionDidChangeAnimated:(BOOL)animated{ NSLog(@"mapView.region.span.latitudeDelta = %f",pMapView.region.span.latitudeDelta); for (id <MKAnnotation> annotation in pMapView.annotations) { MKAnnotationView *annotationView = [pMapView viewForAnnotation: annotation]; } } 

有人可以帮我吗? 谢谢shani

实际上,在默认的MKMapView中,注释(例如pin或图像)和标注(例如气泡)保持与放大或缩小相同的大小。 他们不规模。 但是,我相信你的观点 – 与地图相关,随着地图的放大,地图缩小,缩小。

所以你的问题有两个解决scheme,它们的工作方式稍有不同:

  1. 实现-(void)mapView:(MKMapView *)pMapView regionDidChangeAnimated:(BOOL)animated从MKMapViewDelegate协议参考-(void)mapView:(MKMapView *)pMapView regionDidChangeAnimated:(BOOL)animated – 你已经做了。
  2. 将一个UIPinchGestureRecognizer附加到MKMapView对象,然后执行该操作。

选项#1 – mapView:regionDidChangeAnimated:将被调用的滚动或缩放事件 – 基本上任何时候地图区域更改顾名思义。 这会导致图标的平滑调整稍微不平滑,因为地图事件的触发频率较低。

我的首选项是选项#2 – 将一个UIPinchGestureRecognizer附加到MKMapView对象,然后执行操作。 捏手势事件被激发相当快,所以你得到一个平滑的图标大小。 而且他们只会触发一个公认的捏事件,所以他们不会在滚动事件中触发。

所调用的操作方法必须符合以下签名之一:

- (void)handleGesture;
- (void)handleGesture:(UIGestureRecognizer *)gestureRecognizer;

您必须小心不要覆盖地图的默认缩放行为。 看到这个post:“UIMapView:UIPinchGestureRecognizer不叫”更多信息。 简单的答案是,你必须实现shouldRecognizeSimultaneouslyWithGestureRecognizer:并返回YES。

这里所有告诉的是一些示例代码:

 // Implement viewDidLoad to do additional setup after loading the view, typically from a nib. - (void)viewDidLoad { [super viewDidLoad]; self.mapView.mapType = MKMapTypeStandard; // also MKMapTypeSatellite or MKMapTypeHybrid // Add a pinch gesture recognizer UIPinchGestureRecognizer *pinchRecognizer = [[UIPinchGestureRecognizer alloc] initWithTarget:self action:@selector(handlePinchGesture:)]; pinchRecognizer.delegate = self; [self.mapView addGestureRecognizer:pinchRecognizer]; [pinchRecognizer release]; } #pragma mark - #pragma mark UIPinchGestureRecognizer - (void)handlePinchGesture:(UIPinchGestureRecognizer *)pinchRecognizer { if (pinchRecognizer.state != UIGestureRecognizerStateChanged) { return; } MKMapView *aMapView = (MKMapView *)pinchRecognizer.view; for (id <MKAnnotation>annotation in aMapView.annotations) { // if it's the user location, just return nil. if ([annotation isKindOfClass:[MKUserLocation class]]) return; // handle our custom annotations // if ([annotation isKindOfClass:[MKPointAnnotation class]]) { // try to retrieve an existing pin view first MKAnnotationView *pinView = [aMapView viewForAnnotation:annotation]; //Format the pin view [self formatAnnotationView:pinView forMapView:aMapView]; } } } - (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer { return YES; } 

所以在这一点上,你再次有几个select如何调整注释的大小。 下面的两个代码示例都依赖于Troy Brant的代码来获取MKMapView的缩放级别 。

  1. 使用变换调整注释图像和标注的大小。 就我个人而言,我认为这个转换导致了一个更清晰的外观调整。 但是在大多数情况下,不需要调整标注的大小。
  2. 调整注释图像的大小 – 我使用Trevor Harmon的Resize UIImage正确的方式,但我的意见是,它不是一样干净的resize。

这里是一些更多的示例代码:

 - (void)formatAnnotationView:(MKAnnotationView *)pinView forMapView:(MKMapView *)aMapView { if (pinView) { double zoomLevel = [aMapView zoomLevel]; double scale = -1 * sqrt((double)(1 - pow((zoomLevel/20.0), 2.0))) + 1.1; // This is a circular scale function where at zoom level 0 scale is 0.1 and at zoom level 20 scale is 1.1 // Option #1 pinView.transform = CGAffineTransformMakeScale(scale, scale); // Option #2 UIImage *pinImage = [UIImage imageNamed:@"YOUR_IMAGE_NAME_HERE"]; pinView.image = [pinImage resizedImage:CGSizeMake(pinImage.size.width * scale, pinImage.size.height * scale) interpolationQuality:kCGInterpolationHigh]; } } 

如果这样做,不要忘记标记为答案。

对不起,我的英语不好,但我只是想帮助别人。

非常感谢你,Funktional。 你的答案很好,它完美的工作在iOS5上! 但是这在iOS6上是失效的,现在看来目前还没有解决这个问题的办法。

但最后,我用一种愚蠢/静态的方式解决了这个问题,它在iOS上都能正常工作。 我不会解释太多。 这是我在我的项目中所做的。

  1. mkannotation的图像名为pin.png(大小为20×20)

  2. 我为不同的缩放级别(18×18,16×16,14×14,12×12,10×10)创build了五个不同大小的图像,它们被命名为pin-5.png,pin-4.png,pin-3.png,pin-2.png ,pin-1.png。

  3. 我删除了formatAnnotationView中有关计算比例的所有代码,并添加了这一行

     NSString* imageName = [NSString stringWithFormat:@"%@%@.png", [imageName substringToIndex:[imageName length]-4 ], [self getImageLevel]]; 
  4. 另外,从这个改变

    UIImage * pinImage = [UIImage imageNamed:@“YOUR_IMAGE_NAME_HERE”];

    UIImage * pinImage = [[UIImage alloc] initWithContentsOfFile:imageName];

  5. 添加这个function

     -(NSString *)getImageLevel{ NSString* output; double zoomLevel = [self getZoomLevel:_mapview]; if(zoomLevel >= 19.0) output = @""; else if(zoomLevel < 19.0 && zoomLevel >= 18.0) output = @"-5"; else if(zoomLevel < 18.0 && zoomLevel >= 17.0) output = @"-4"; else if(zoomLevel < 17.0 && zoomLevel >= 16.0) output = @"-3"; else if(zoomLevel < 16.0 && zoomLevel >= 15.0) output = @"-2"; else output = @"-1"; return output;} 

对不起的代码和英语再次抱歉。

另一种方法是重新调整注解视图图像属性的大小。 在这篇文章中显示了一个例子

在Swift 3中,这为我工作。 我的图像是19级100%,所以1/19给我0.5263158这是我的线性尺度:

 func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? { if annotation is MKUserLocation { return nil } let mkView = MKAnnotationView(annotation: annotation, reuseIdentifier: "mkView") mkView.image = UIImage(named: "Foo") formatAnnotation(pinView: mkView, forMapView: mapView) return mkView; } func formatAnnotation(pinView: MKAnnotationView, forMapView: MKMapView) { let zoomLevel = forMapView.getZoomLevel() let scale = 0.05263158 * zoomLevel //Modify to whatever scale you need. pinView.transform = CGAffineTransform(scaleX: CGFloat(scale), y: CGFloat(scale)) } 

@Funktional在Swift 3中的回答:

 class MapViewController: UIViewController: UIGestureRecognizerDelegate { @IBOutlet weak var mapView: MKMapView! override func viewDidLoad() { super.viewDidLoad() // You can also add this gesture recognizer and set the delegate via storyboard let pinchGR = UIPinchGestureRecognizer(target: self, action: #selector(handlePinchGesture)) pinchGR.delegate = self self.mapView.addGestureRecognizer(pinchGR) } // link as @IBAction when added via storyboard func handlePinchGesture(_ sender: UIPinchGestureRecognizer) { if sender.state == .ended { for annotation in mapView.annotations { if annotation is MKUserLocation { continue } guard let annotationView = self.mapView.view(for: annotation) else { continue } let scale = -1 * sqrt(1 - pow(mapView.zoomLevel / 20, 2.0)) + 1.4 annotationView.transform = CGAffineTransform(scaleX: CGFloat(scale), y: CGFloat(scale)) } } } func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldRecognizeSimultaneouslyWith otherGestureRecognizer: UIGestureRecognizer) -> Bool { return true } } extension MKMapView { var zoomLevel: Double { return log2(360 * ((Double(self.frame.size.width) / 256) / self.region.span.longitudeDelta)) - 1 } }