我有什么
我在地图上有大约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
答案 0 :(得分:25)
实际上在默认的MKMapView上 - 注释(例如图钉或图像)和标注(例如气泡)保持与放大或缩小相同的尺寸。他们没有规模。但是当地图放大时,随着地图缩小和缩小,我得到了与地图的关系,它们看起来正在增长。
因此,您的问题有两种解决方案,它们的工作方式略有不同:
-(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。
以下是一些示例代码:
- (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];
}
}
如果有效,请不要忘记将其标记为答案。
答案 1 :(得分:1)
抱歉我的英语不好......但我只想帮助别人。
非常感谢你,Funktional。你的答案很棒......它完全适用于iOS5!但这在iOS6上无效,现在似乎没有解决方案来解决这个问题。
但最后,我以愚蠢/静态的方式解决了它,它在iOS上都运行良好。我不会解释太多。这就是我在项目中所做的。
mkannotation的图像名为pin.png(大小为20x20)
我为不同的缩放级别创建了五个不同大小的图像(18x18,16x16,14x14,12x12,10x10),它们被命名为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 alloc] 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;}
对于糟糕的编码和英语再次抱歉。
答案 2 :(得分:1)
另一种方法是重新调整注释视图图像属性的大小。一个例子是shown in this post
答案 3 :(得分:1)
在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))
}
答案 4 :(得分:1)
@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
}
}