将子视图添加到地图上方但注释视图下方的 MKMapView?

发布于 2024-08-09 02:06:36 字数 299 浏览 7 评论 0原文

对于我正在构建的应用程序,我有一个自定义的“旧地图”效果 PNG,我想将其叠加在 MKMapView 视图上。不幸的是,我尝试这样做的两种方法都不完全正确:

  1. 向 MKMapView 添加一个子视图(问题:PNG 的 UIImageView 被放置在注释引脚的上方,这看起来很奇怪
  2. 。 注释视图图像,并且有一段时间只有常规地图而不是老式效果)。

注释视图本身并将其放置在其他视图下方(问题:在滚动时,我必须移动 有一个子视图位于地图图块上方但注释视图下方,并且当用户滚动时该子视图将保持稳定 - 有什么想法吗?

For an app I'm building, I have a custom "old map" effect PNG that I'd like to overlay on the MKMapView view. Unfortunately, neither way I've tried to do this is exactly right:

  1. Add a subview to the MKMapView (issue: the UIImageView for the PNG gets placed above the Annotation pins, which looks weird
  2. Make the image an annotation view itself and place it below the other ones (issue: on scroll, I have to move the annotation view image, and for a while there's just the regular map instead of the old-timey-effect).

What I basically want to accomplish is having a subview that is layered above the maptiles but below the annotation views, and that will hold steady while the user scrolls around—any thoughts?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

决绝 2024-08-16 02:06:36

请注意,所有 MKMapView 子视图层次结构、注释、行为等均在内部私有 MKMapViewInternal 类,因此更改此结构中的任何内容(以我建议的方式或其他方式)可能会导致您的应用程序被 Appstore 拒绝。

我没有完整的解决方案,只是一个想法。我的想法是使覆盖视图与注释视图具有相同的超级视图,并确保注释将放置在我们的覆盖层上。在 MKMapViewDelegate 中,我们实现:

- (void)mapView:(MKMapView *)aMapView didAddAnnotationViews:(NSArray *)views{
    if (views.count > 0){
        UIView* tView = [views objectAtIndex:0];

        UIView* parView = [tView superview];
        UIView* overlay = [tView viewWithTag:2000];
        if (overlay == nil){
            overlay = [[UIImageView alloc] initWithImage:[UIImage imageNamed:MY_IMAGE_NAME]];
            overlay.frame = parView.frame; //frame equals to (0,0,16384,16384)
            overlay.tag = 2000;
            overlay.alpha = 0.7;
            [parView addSubview:overlay];
            [overlay release];
        }

        for (UIView* view in views)
            [parView bringSubviewToFront:view];
    }
}

此代码完成了您想要的一半工作 - 您将获得一个放置在地图图块和注释之间的视图。剩下的任务是根据地图滚动/缩放更改自定义叠加视图框架(如果我找到方法,我会发布)。

Note that all MKMapView subviews hierarchy, annotations, behaviour etc proceeds in internal private MKMapViewInternal class so changing anything (in a way I suggest or another) in this structure may cause your application to be rejected from Appstore.

I do not have a full solution, just an idea. My idea is to make an overlay view have the same superview as annotation views and ensure that annotations will be placed over our overlay. In MKMapViewDelegate we implement:

- (void)mapView:(MKMapView *)aMapView didAddAnnotationViews:(NSArray *)views{
    if (views.count > 0){
        UIView* tView = [views objectAtIndex:0];

        UIView* parView = [tView superview];
        UIView* overlay = [tView viewWithTag:2000];
        if (overlay == nil){
            overlay = [[UIImageView alloc] initWithImage:[UIImage imageNamed:MY_IMAGE_NAME]];
            overlay.frame = parView.frame; //frame equals to (0,0,16384,16384)
            overlay.tag = 2000;
            overlay.alpha = 0.7;
            [parView addSubview:overlay];
            [overlay release];
        }

        for (UIView* view in views)
            [parView bringSubviewToFront:view];
    }
}

This code does a half of what you want - you get a view placed between map tiles and annotations. The remaining task is to change custom overlay view frame according to map scrolling/zooming (I'll post if I find the way).

街道布景 2024-08-16 02:06:36

我最终以不同的方式做了类似的事情。我想通过添加白色覆盖来淡出地图视图,但我不想淡出注释。我在地图上添加了一个叠加层(实际上我必须添加两个,因为它不喜欢我尝试为整个地球添加叠加层)。

CLLocationCoordinate2D pt1, pt2, pt3, pt4;
pt1 = CLLocationCoordinate2DMake(85, 0);
pt2 = CLLocationCoordinate2DMake(85, 180);
pt3 = CLLocationCoordinate2DMake(-85, 180);
pt4 = CLLocationCoordinate2DMake(-85, 0);
CLLocationCoordinate2D coords[] = {pt1, pt2, pt3, pt4};
MKPolygon *p = [MKPolygon polygonWithCoordinates:coords count:4];
[self.mapView addOverlay:p];

pt1 = CLLocationCoordinate2DMake(85, 0);
pt2 = CLLocationCoordinate2DMake(85, -180);
pt3 = CLLocationCoordinate2DMake(-85, -180);
pt4 = CLLocationCoordinate2DMake(-85, 0);
CLLocationCoordinate2D coords2[] = {pt1, pt2, pt3, pt4};
MKPolygon *p2 = [MKPolygon polygonWithCoordinates:coords2 count:4];
[self.mapView addOverlay:p2];

然后你需要添加地图委托来绘制它们:

- (MKOverlayRenderer *)mapView:(MKMapView *)mapView rendererForOverlay:(id<MKOverlay>)overlay {
    if ([overlay isKindOfClass:MKPolygon.class]) {
        MKPolygonRenderer *polygonView = [[MKPolygonRenderer alloc] initWithOverlay:overlay];
        polygonView.fillColor = [UIColor colorWithRed:255.0/255.0 green:255.0/255.0 blue:255.0/255.0 alpha:0.4];
        return polygonView;
    }
    return nil;
}

I did something similar and in a different way in the end. I wanted to fade the mapview out by adding a white overlay, but I didn't want to fade the annotations. I added an overlay to the map (actually I had to add two as it didn't like me trying to add an overlay for the entire globe).

CLLocationCoordinate2D pt1, pt2, pt3, pt4;
pt1 = CLLocationCoordinate2DMake(85, 0);
pt2 = CLLocationCoordinate2DMake(85, 180);
pt3 = CLLocationCoordinate2DMake(-85, 180);
pt4 = CLLocationCoordinate2DMake(-85, 0);
CLLocationCoordinate2D coords[] = {pt1, pt2, pt3, pt4};
MKPolygon *p = [MKPolygon polygonWithCoordinates:coords count:4];
[self.mapView addOverlay:p];

pt1 = CLLocationCoordinate2DMake(85, 0);
pt2 = CLLocationCoordinate2DMake(85, -180);
pt3 = CLLocationCoordinate2DMake(-85, -180);
pt4 = CLLocationCoordinate2DMake(-85, 0);
CLLocationCoordinate2D coords2[] = {pt1, pt2, pt3, pt4};
MKPolygon *p2 = [MKPolygon polygonWithCoordinates:coords2 count:4];
[self.mapView addOverlay:p2];

Then you need to add the map delegate to draw them:

- (MKOverlayRenderer *)mapView:(MKMapView *)mapView rendererForOverlay:(id<MKOverlay>)overlay {
    if ([overlay isKindOfClass:MKPolygon.class]) {
        MKPolygonRenderer *polygonView = [[MKPolygonRenderer alloc] initWithOverlay:overlay];
        polygonView.fillColor = [UIColor colorWithRed:255.0/255.0 green:255.0/255.0 blue:255.0/255.0 alpha:0.4];
        return polygonView;
    }
    return nil;
}
鹿! 2024-08-16 02:06:36

它已经很老了,但也许对你们中的一些人仍然有意义。

我想让地图变暗,而不是注释视图。

我所做的非常简单,我还不知道它是否有一些后备...

我在 MKMapView 上方放置了一个带有黑色透明背景的 UIView ,并且然后添加以下代码:

- (void)mapView:(MKMapView *)mapView didAddAnnotationViews:(NSArray<MKAnnotationView *> *)views
{
    for (MKAnnotationView *view in views) {
        view.center = [self.mapView convertCoordinate:view.annotation.coordinate toPointToView:self.viewDark];
        [self.viewDark addSubview:view];
    }
}

希望它有帮助..当然 - 如果您发现有关此解决方案的任何问题,请告诉我:)

编辑#1:
忘记提及 self.viewDark 应该禁用 userInteraction

编辑#2:
另一件对我有帮助的事情是将 self.viewDarkautoresizesSubviews 设置为 NO

It's pretty old, but maybe still relevant for some of you.

I wanted to make the map darker, but not the annotation views.

What i did was very simple and i don't yet know if it has some fallbacks...

I put a UIView with a black-transparent background above the MKMapView, and then added the following code:

- (void)mapView:(MKMapView *)mapView didAddAnnotationViews:(NSArray<MKAnnotationView *> *)views
{
    for (MKAnnotationView *view in views) {
        view.center = [self.mapView convertCoordinate:view.annotation.coordinate toPointToView:self.viewDark];
        [self.viewDark addSubview:view];
    }
}

Hope it helps.. and of course - if you find any issues about this solution please let me know :)

Edit #1:
Forgot to mention that self.viewDark should have userInteraction disabled.

Edit #2:
Another thing that helped me is setting self.viewDark's autoresizesSubviews to NO.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文