正确使用MKOverlayView [英] Proper use of MKOverlayView

查看:139
本文介绍了正确使用MKOverlayView的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在编写一个iPhone应用程序,其中使用MKOverlayView在MKMapView上放置了一个较大的PNG图像(1936××2967).我对如何适当地实现MKOverlayView中的drawMapRect:函数有些困惑-在绘制图像之前我应该​​手动分割图像吗?还是应该让MKOverlayView机制处理所有这些?

I am writing an iPhone app in which I place a large PNG image (1936 × 2967) on an MKMapView using MKOverlayView. I am a little confused about how to appropriately implement the drawMapRect: function in MKOverlayView - should I manually segment my image before drawing it? Or should I let the mechanisms of MKOverlayView handle all that?

我从其他帖子中得到的印象是,在MKOverlayView可用之前,您应该针对这种任务自己分割图像,并使用CATiledLayer.我以为MKOverlayView可以处理所有肮脏的工作.

My impression from other posts is that before MKOverlayView was available, you were expected to segment images yourself for this kind of task, and use a CATiledLayer. I thought maybe MKOverlayView took care of all the dirty work.

我问的真正原因是因为当我使用分配"工具通过Instruments运行我的应用程序时,我发现随着地图上引入自定义图像,我的应用程序正在使用的实时字节数稳步增加.现在,我没有对图像进行分段,但是在Instruments的泄漏工具中也看不到内存泄漏的记录.这是我的drawMapRect:函数:

The real reason I ask though is because when I run my app through Instruments using the allocations tool, I find that the number of live bytes my app is using steadily increases with the introduction of the custom image on the map. Right now I am NOT segmenting my image, but I also am seeing no record of memory leaks in the leaks tool in Instruments. Here is my drawMapRect: function:

- (void)drawMapRect:(MKMapRect)mapRect zoomScale:(MKZoomScale)zoomScale inContext:(CGContextRef)context{
    // Load image from applicaiton bundle
    NSString* imageFileName = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:@"map.png"];
    CGDataProviderRef provider = CGDataProviderCreateWithFilename([imageFileName UTF8String]);
    CGImageRef image = CGImageCreateWithPNGDataProvider(provider, NULL, true, kCGRenderingIntentDefault);
    CGDataProviderRelease(provider);

    MKMapRect overlayMapRect = [self.overlay boundingMapRect];
    CGRect overlayRect = [self rectForMapRect:overlayMapRect];

    // draw image
    CGContextSaveGState(context);
    CGContextDrawImage(context, overlayRect, image);
    CGContextRestoreGState(context);

    CGImageRelease(image);

}

如果我的drawMapRect:函数不是导致这些内存问题的原因,有人知道它可能是什么吗?通过调试,我知道mapView的viewForOverlay:函数仅对每个叠加层调用一次,因此并不是那里的内存泄漏了.

If my drawMapRect: function is not the cause of these memory issues, does anybody know what it might be? I know through debugging that my viewForOverlay: function for the mapView only gets called once for each overlay, so it's not that memory is leaking there or something.

欢迎任何建议!

谢谢-马特

因此事实证明,内存问题实际上是由MKMapView引起的-每次我移动地图时,内存使用量都非常稳定地上升,而从未下降-这似乎不太好:(

so it turns out that the memory issue is actually being caused by MKMapView - every time I move the map at all the memory usage goes up very steadily and never comes down - this doesn't seem good :(

推荐答案

答案有点晚,如果将来有人遇到同样的问题,请把答案留在这里.此处的缺陷是试图在文档明确说明的情况下渲染整个图像-

A bit of a late answer, leaving it here if somebody else hits the same problem in the future. The flaw here is trying to render a whole image while documentation clearly says -

此外,每次调用此方法时,都应避免绘制覆盖层的全部内容.相反,请始终考虑mapRect参数,并避免在该矩形之外绘制内容.

In addition, you should avoid drawing the entire contents of the overlay each time this method is called. Instead, always take the mapRect parameter into consideration and avoid drawing content outside that rectangle.

因此,您只需要在mapRect定义的区域中绘制图像的一部分

so, you have to only draw the part of the image in the area defined by mapRect

已更新:请记住,这里的drawRect可以大于mapRect,需要相应地调整绘制并剪切区域

updated: keep in mind that drawRect here can be larger than mapRect, need to adjust the paint and cut regions accordingly

let overlayMapRect = overlay.boundingMapRect
let overlayDrawRect = self.rect(for: overlayMapRect)

// watch out for draw rect adjustment here --
let drawRect = self.rect(for: mapRect).intersection(overlayDrawRect)
let scaleX = CGFloat(image.width) / overlayRect.width
let scaleY = CGFloat(image.height) / overlayRect.height
let transform = CGAffineTransform.init(scaleX: scaleX, y: scaleY)
let imageCut = drawRect.applying(transform)

// omitting optionals checks, you should not
let cutImage = image.cropping(to: imageCut)

// the usual vertical flip issue with image.draw
context.translateBy(x: 0, y: drawRect.maxY + drawRect.origin.y)
context.scaleBy(x: 1, y: -1)
context.draw(image, in: drawRect, byTiling: false)

这篇关于正确使用MKOverlayView的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆