MkMapView 取消加载谷歌图块

发布于 2024-10-22 06:31:11 字数 111 浏览 1 评论 0原文

我有一个情况,我需要在 MkMapView 顶部导入叠加地图。 覆盖层完全覆盖了下面的谷歌图块,因此不需要加载,而且它增加了应用程序的开销。

有没有办法告诉 mkMapView 停止加载图块?

I have a case where I need to import an overlay map in top of MkMapView.
The overlay totally covers the google tiles below so there is no need loading, plus it adds overhead to the app.

Is there a way to tell mkMapView to stop loading tiles?

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

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

发布评论

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

评论(3

梦境 2024-10-29 06:31:11

实际上有两种方法可以实现真正的“隐藏 Google 磁贴”方法(johndope 解决方案仅在其顶部放置一个覆盖层,但不会阻止磁贴加载)。

请注意,下面描述的选项一可能会导致您的申请被拒绝,而选项 2 则不会,但有点复杂。

公共部分:检索MKMapTileView对象

在每个MKMapView内部都有一个未记录的类型的类:MKMapTileView。检索它不是拒绝的理由。在此代码中,MKMapView 实例将被称为 mapView

UIView* scrollview = [[[[mapView subviews] objectAtIndex:0] subviews] objectAtIndex:0];
UIView* mkTiles = [[scrollview subviews] objectAtIndex:0]; // <- MKMapTileView instance

选项 1:未记录的方法(!!可能成为拒绝的原因!!)

if ( [mkTiles respondsToSelector:@selector(setDrawingEnabled:)])
    [mkTiles performSelector:@selector(setDrawingEnabled:) withObject:(id)NO];

这将防止在 MKMapTileView 实例上调用未记录的方法 setDrawingEnabled

选项 2:方法调整

在控制器实现之外,您将编写如下内容:

// Import runtime.h to unleash the power of objective C 
#import <objc/runtime.h>

// this will hold the old drawLayer:inContext: implementation
static void (*_origDrawLayerInContext)(id, SEL, CALayer*, CGContextRef);

// this will override the drawLayer:inContext: method
static void OverrideDrawLayerInContext(UIView *self, SEL _cmd, CALayer *layer, CGContextRef context)
{
    // uncommenting this next line will still perform the old behavior
    //_origDrawLayerInContext(self, _cmd, layer, context);

    // change colors if needed so that you don't have a black background
    layer.backgroundColor = RGB(35, 160, 211).CGColor;

    CGContextSetRGBFillColor(context, 35/255.0f, 160/255.0f, 211/255.0f, 1.0f);
    CGContextFillRect(context, layer.bounds);
}

在代码中的某个位置(加载地图视图后!):

// Retrieve original method object
Method  origMethod = class_getInstanceMethod([mkTiles class], 
                                             @selector(drawLayer:inContext:));

// from this method, retrieve its implementation (actual work done)
_origDrawLayerInContext = (void *)method_getImplementation(origMethod);

// override this method with the one you created    
if(!class_addMethod([mkTiles class],
                    @selector(drawLayer:inContext:), 
                    (IMP)OverrideDrawLayerInContext,
                    method_getTypeEncoding(origMethod)))
{
    method_setImplementation(origMethod, (IMP)OverrideDrawLayerInContext);
}

希望这对任何人都有帮助,该代码最初在此描述博文

Actually there are 2 ways to implement the real "Hide Google tiles" method (johndope solution only puts an overlay on top of it but doesn't prevent the tiles from loading).

Beware that option one described below might get your application rejected while option 2 will not but is a bit more complex.

Common Part: Retrieve the MKMapTileView object

Inside each MKMapView lies an undocumented class of type: MKMapTileView. Retrieving it is NOT a reason for rejection. In this code the MKMapView instance will be called mapView

UIView* scrollview = [[[[mapView subviews] objectAtIndex:0] subviews] objectAtIndex:0];
UIView* mkTiles = [[scrollview subviews] objectAtIndex:0]; // <- MKMapTileView instance

Option 1: Undocumented Method (!! can be a reason for rejection !! )

if ( [mkTiles respondsToSelector:@selector(setDrawingEnabled:)])
    [mkTiles performSelector:@selector(setDrawingEnabled:) withObject:(id)NO];

This will prevent the undocumented method setDrawingEnabled to be called on the MKMapTileView instance.

Option 2: Method Swizzling

Outside of your controller implementation you will write someting like:

// Import runtime.h to unleash the power of objective C 
#import <objc/runtime.h>

// this will hold the old drawLayer:inContext: implementation
static void (*_origDrawLayerInContext)(id, SEL, CALayer*, CGContextRef);

// this will override the drawLayer:inContext: method
static void OverrideDrawLayerInContext(UIView *self, SEL _cmd, CALayer *layer, CGContextRef context)
{
    // uncommenting this next line will still perform the old behavior
    //_origDrawLayerInContext(self, _cmd, layer, context);

    // change colors if needed so that you don't have a black background
    layer.backgroundColor = RGB(35, 160, 211).CGColor;

    CGContextSetRGBFillColor(context, 35/255.0f, 160/255.0f, 211/255.0f, 1.0f);
    CGContextFillRect(context, layer.bounds);
}

And somewhere in your code (once your map view is loaded!) :

// Retrieve original method object
Method  origMethod = class_getInstanceMethod([mkTiles class], 
                                             @selector(drawLayer:inContext:));

// from this method, retrieve its implementation (actual work done)
_origDrawLayerInContext = (void *)method_getImplementation(origMethod);

// override this method with the one you created    
if(!class_addMethod([mkTiles class],
                    @selector(drawLayer:inContext:), 
                    (IMP)OverrideDrawLayerInContext,
                    method_getTypeEncoding(origMethod)))
{
    method_setImplementation(origMethod, (IMP)OverrideDrawLayerInContext);
}

Hope this helps anyone, this code was originally described in this blog post.

舞袖。长 2024-10-29 06:31:11

据我所知,您无法阻止 MKMapView 加载 Google 地图图块,并且如果您的应用在显示 MKMapView 时遮盖了 Google 徽标,则有可能会被拒绝> - 您可能需要考虑编写自定义 UIScrollView 来显示您的地图。

As far as I know you can't prevent MKMapView from loading Google Maps tiles, and there's a chance your app will be rejected if it covers up the Google logo while displaying an MKMapView – you may want to consider writing a custom UIScrollView to display your map instead.

べ繥欢鉨o。 2024-10-29 06:31:11

我遇到了一个相关的问题,但就我而言,我的叠加层没有覆盖所有谷歌图块。
如果有人遇到这个问题,并且试图停止加载谷歌图块,我设法在谷歌地图图块上叠加一个灰色图块(256x256)覆盖层。
为此,顶层图块必须是
/FakeTiles/1/1/0.png 并将此目录添加到项目的资源中。
(注意,不要将其拖到项目 > 添加文件 > 文件夹 > 为任何文件夹创建文件夹引用),

//hack to overlay grey tiles
NSString *fakeTileDirectory = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:@"FakeTiles"];
TileOverlay *greyOverlay = [[TileOverlay alloc] initWithTileDirectory:fakeTileDirectory];
[mapView addOverlay:greyOverlay];
[greyOverlay release];

然后添加自定义图块叠加层。

然后你需要这段代码来缩放灰色瓷砖
计算要显示的图块当“过度缩放”超出覆盖图块集时在 MapRect 中

I encountered a related problem but in my case my overlay didn't cover all the google tiles.
If anyone has this problem, and is trying to stop loading the google tiles, I managed to superimpose one gray tile(256x256) overlay over the google map tiles.
To do this, the top level tile must be
/FakeTiles/1/1/0.png and add this directory to resources to project.
(N.B. don't drag this into project > Add files > Folders > Create folder references for any folders)

//hack to overlay grey tiles
NSString *fakeTileDirectory = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:@"FakeTiles"];
TileOverlay *greyOverlay = [[TileOverlay alloc] initWithTileDirectory:fakeTileDirectory];
[mapView addOverlay:greyOverlay];
[greyOverlay release];

then add your custom tile overlay.

Then you need this code to scale the grey tile
Calculating tiles to display in a MapRect when "over-zoomed" beyond the overlay tile set

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