调整MKAnnotationView图像当地图放大和缩小时?
我还有什么调整MKAnnotationView图像当地图放大和缩小时?
我在地图上有大约150个MKAnnotationViews。每个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-注释(例如销或图像)和标注(例如气泡)保持相同的尺寸你在放大或缩小。它们不会缩放。但我明白你的点对多点相对于地图,他们似乎成长为地图缩小和收缩的地图在放大
所以有两种解决方案,您的问题和他们的工作方式略有不同:
- 从MKMapViewDelegate协议参考实现
-(void)mapView:(MKMapView *)pMapView regionDidChangeAnimated:(BOOL)animated
- 你已经完成了。 - 将
UIPinchGestureRecognizer
附加到MKMapView对象,然后执行操作。
选项#1 - mapView:regionDidChangeAnimated:
将呼吁无论是滚动或缩放事件 - 基本上任何时候在地图区域改变顾名思义。这会导致图标大小稍微平滑,因为地图事件触发的频率较低。
我的偏好适用于选项#2 - 将UIPinchGestureRecognizer
附加到MKMapView对象,然后执行该操作。捏手势事件会很快被触发,所以您可以顺利调整图标大小。而且他们只会触发一个公认的捏事件 - 所以他们不会在滚动事件期间触发。
调用必须符合以下特征之一的操作方法:
- (void)handleGesture;
- (void)handleGesture:(UIGestureRecognizer *)gestureRecognizer;
你必须要小心,不要覆盖地图默认缩放行为。看到这篇文章:“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;
}
所以在这个点 - 你再有如何调整注释的几个选项。以下两个代码示例均依赖于Troy Brant's code for getting the zoom level of an MKMapView。
- 同时调整注释图像和使用变换该标注。就我个人而言,我认为这个转变会带来更清晰的外观调整。但在大多数情况下,不需要调整标注的大小。
- 只调整注释图像 - 我使用Trevor Harmon's Resize a UIImage the right way但我的意见是,它不是一样干净的调整大小。
下面是一些示例代码:
- (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上都能正常工作。我不会解释太多。这是我在我的项目中所做的。
用于mkannotation的图像被命名为pin.png(尺寸20×20是)
我创建了五个更多的图像具有不同的大小不同的缩放等级(18×18,16×16,14×14,12×12,10×10 ),它们被命名为pin-5.png,pin-4.png,pin-3.png,pin-2.png,pin-1.png。
-
我删除所有的代码有关formatAnnotationView计算规模,并加入该行
NSString* imageName = [NSString stringWithFormat:@"%@%@.png", [imageName substringToIndex:[imageName length]-4 ], [self getImageLevel]];
-
另外,从
的UIImage * pinImage =更改此[UIImage的imageNamed:@ “YOUR_IMAGE_NAME_HERE”];
到
的UIImage * pinImage = [[UIImage的页头] initWithContentsOfFile:imageName];
-
添加此功能
-(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在斯威夫特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
}
}
嘿。我会尝试这个,谢谢你的一个很好的答案。并且不需要担心:) – shannoga
这在iOS6上无效 – user501836
这是正确的,不再适用于iOS6。任何人都想出了一个解决方案? – Bach