如何自定义 MKAnnotationView 的标注气泡?
我目前正在使用地图套件,但遇到了困难。
我正在使用一个自定义注释视图,我想使用 image 属性用我自己的图标在地图上显示该点。我这个工作正常。但我还想做的是覆盖默认的标注视图(触摸注释图标时与标题/副标题一起显示的气泡)。我希望能够控制标注本身:mapkit 只提供对左侧和右侧辅助标注视图的访问,但无法为标注气泡提供自定义视图,或者为其提供零大小或其他任何内容。
我的想法是重写 MKMapViewDelegate
中的 selectAnnotation/deselectAnnotation,然后通过调用我的自定义注释视图来绘制我自己的自定义视图。这有效,但仅当在我的自定义注释视图类中将 canShowCallout
设置为 YES
时才有效。如果我将此设置为 NO
(这就是我想要的,这样就不会绘制默认标注气泡),则不会调用这些方法。因此,在没有显示默认标注气泡视图的情况下,我无法知道用户是否触摸了地图上的我的点(选择了它)或触摸了不属于我的注释视图的点(删除了它)。
我尝试走不同的路径,自己处理地图中的所有触摸事件,但我似乎无法正常工作。我阅读了与在地图视图中捕获触摸事件相关的其他帖子,但它们并不完全是我想要的。有没有办法在绘制之前深入地图视图以删除标注气泡?我不知所措。
有什么建议吗?我错过了一些明显的东西吗?
I'm currently working with the mapkit and am stuck.
I have a custom annotation view I am using, and I want to use the image property to display the point on the map with my own icon. I have this working fine. But what I would also like to do is to override the default callout view (the bubble that shows up with the title/subtitle when the annotation icon is touched). I want to be able to control the callout itself: the mapkit only provides access to the left and right ancillary callout views, but no way to provide a custom view for the callout bubble, or to give it zero size, or anything else.
My idea was to override selectAnnotation/deselectAnnotation in my MKMapViewDelegate
, and then draw my own custom view by making a call to my custom annotation view. This works, but only when canShowCallout
is set to YES
in my custom annotation view class. These methods are NOT called if I have this set to NO
(which is what I want, so that the default callout bubble is not drawn). So I have no way of knowing if the user touched on my point on the map (selected it) or touched a point that is not part of my annotation views (delected it) without having the default callout bubble view show up.
I tried going down a different path and just handling all touch events myself in the map, and I can't seem to get this working. I read other posts related to catching touch events in the map view, but they aren't exactly what I want. Is there a way to dig into the map view to remove the callout bubble before drawing? I'm at a loss.
Any suggestions? Am I missing something obvious?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(9)
还有一个更简单的解决方案。
创建一个自定义
UIView
(用于您的标注)。然后创建
MKAnnotationView
的子类并重写setSelected
,如下所示:Boom,工作完成。
There is an even easier solution.
Create a custom
UIView
(for your callout).Then create a subclass of
MKAnnotationView
and overridesetSelected
as follows:Boom, job done.
。
在过去,这是一个痛苦的问题,但 Apple 已经解决了它,只需检查 MKAnnotationView
真的,就是这样。接受任何 UIView。
detailCalloutAccessoryView
In the olden days this was a pain, but Apple has solved it, just check the docs on MKAnnotationView
Really, that's it. Takes any UIView.
继续@TappCandy 非常简单的答案,如果您想以与默认气泡相同的方式为气泡设置动画,我已经制作了这个动画方法:
它看起来相当复杂,但只要设计了标注气泡的点即可要成为中心底部,您应该能够将
myBubbleWidth
和myBubbleHeight
替换为您自己的大小才能正常工作。请记住确保您的子视图的autoResizeMask
属性设置为 63(即“全部”),以便它们在动画中正确缩放。:-乔
Continuing on from @TappCandy's brilliantly simple answer, if you want to animate your bubble in the same way as the default one, I've produced this animation method:
It looks fairly complicated, but as long as the point of your callout bubble is designed to be centre-bottom, you should just be able to replace
myBubbleWidth
andmyBubbleHeight
with your own size for it to work. And remember to make sure your subviews have theirautoResizeMask
property set to 63 (i.e. "all") so that they scale correctly in the animation.:-Joe
发现这对我来说是最好的解决方案。
您必须使用一些创造力来进行自己的自定义
在您的
MKAnnotationView
子类中,您可以使用And if the
subview
is aUICalloutView
,然后你就可以随意摆弄它以及里面的东西了。Found this to be the best solution for me.
You'll have to use some creativity to do your own customizations
In your
MKAnnotationView
subclass, you can useAnd if the
subview
is aUICalloutView
, then you can screw around with it, and what's inside it.我也有同样的问题。此博客上有大量关于此主题的博客文章 http://spitzkoff.com/craig/ ?p=81。
仅使用 MKMapViewDelegate 在这里并不能帮助您,子类化 MKMapView 并尝试扩展现有功能对我来说也不起作用。
我最终要做的是创建我自己的
CustomCalloutView
,并将其置于我的MKMapView
之上。您可以按照您想要的任何方式设置此视图的样式。我的
CustomCalloutView
有一个与此类似的方法:它采用一个
MKAnnotation
对象并设置自己的标题,然后调用另外两个非常难看的方法,分别调整宽度和标注内容的大小,然后在其周围的正确位置绘制对话气泡。最后,该视图作为子视图添加到mapView 中。该解决方案的问题在于,当地图视图滚动时,很难将标注保持在正确的位置。我只是将标注隐藏在区域更改的地图视图委托方法中以解决此问题。
解决所有这些问题花了一些时间,但现在标注的行为几乎与官方的一样,但我有自己的风格。
I had the same problem. There is a serious of blog posts about this topic on this blog http://spitzkoff.com/craig/?p=81.
Just using the
MKMapViewDelegate
doesn't help you here and subclassingMKMapView
and trying to extend the existing functionality also didn't work for me.What I ended up doing is to create my own
CustomCalloutView
that I am having on top of myMKMapView
. You can style this view in any way you want.My
CustomCalloutView
has a method similar to this one:It takes an
MKAnnotation
object and sets its own title, afterward it calls two other methods which are quite ugly which adjust the width and size of the callout contents and afterward draw the speech bubble around it at the correct position.Finally the view is added as a subview to the mapView. The problem with this solution is that it is hard to keep the callout at the correct position when the map view is scrolled. I am just hiding the callout in the map views delegate method on a region change to solve this problem.
It took some time to solve all those problems, but now the callout almost behaves like the official one, but I have it in my own style.
基本上要解决这个问题,需要:
a) 防止出现默认标注气泡。
b) 找出单击了哪个注释。
我能够通过以下方式实现这些目标:
a) 将 canShowCallout 设置为 NO
b) 子类化、MKPinAnnotationView 并覆盖touchesBegan 和touchesEnd 方法。
注意:您需要处理 MKAnnotationView 而不是 MKMapView 的触摸事件
Basically to solve this, one needs to:
a) Prevent the default callout bubble from coming up.
b) Figure out which annotation was clicked.
I was able to achieve these by:
a) setting canShowCallout to NO
b) subclassing, MKPinAnnotationView and overriding the touchesBegan and touchesEnd methods.
Note: You need to handle the touch events for the MKAnnotationView and not MKMapView
我只是想出了一种方法,这里的想法是
- testview 是一个大小为 320x100 的
UIView
- showCallout 是 BOOL -[self animateIn];
是执行此操作的函数查看动画,如UIAlertView
。I just come up with an approach, the idea here is
Here - testview is a
UIView
of size 320x100 - showCallout is BOOL -[self animateIn];
is the function that does view animation likeUIAlertView
.您可以使用 leftCalloutView,将annotation.text 设置为 @" "
请在下面找到示例代码:
You can use leftCalloutView, setting annotation.text to @" "
Please find below the example code:
我已经推出了优秀的 SMCalloutView 的分支,它解决了为标注提供自定义视图并允许灵活的宽度/高度的问题。还有一些怪癖需要解决,但到目前为止它非常实用:
https://github.com/u10int/calloutview
I've pushed out my fork of the excellent SMCalloutView that solves the issue with providing a custom view for callouts and allowing flexible widths/heights pretty painlessly. Still some quirks to work out, but it's pretty functional so far:
https://github.com/u10int/calloutview