当用户平移或缩放地图时,根据对MKMapView的更改,我需要重绘一些UI。
目前我正在使用移动事件手势识别器和MKMapViewDelegate regionDidChangeAnimated消息来重绘我的依赖UI。这是我需要的90%。
我失踪的事件是从用户抬起手指(不再移动事件)到触发MKMapViewDelegate regionDidChangeAnimated消息的时间点。在此期间,地图缓慢停止,我的依赖用户界面停留在不同步的地图图块内容中。
当重绘UIView(在本例中为MKMapView)内容时,是否会有一个较低级别的API通知我?
更新
我尝试创建一个代理MKMapView子类,它将drawRect调用转发到我提供的委托。我得到了第一次抽奖活动,但后来都没有,所以这对我的困境没有帮助。
答案 0 :(得分:2)
IIRC,遗憾的是@"region"
NSTimer
为regionWillChangeAnimated
。
您可能会在regionDidChangeAnimated
中设置UIScrollView
,在滚动/平移/等等过程中使用它来刷新UI,并在transform
中丢弃它。虽然不太优雅,如果你需要非常快,它可能不适合你的需要。
或者,您可以在MKMapView的子视图中查找MKMapView
,并观察其MKMapView
。
(我没有测试过这些。)
无论如何,我怀疑监视CATiledLayer
上的重绘事件是否有用:{{1}}使用{{1}}异步执行绘图,所以你甚至不能确定何时完成。
编辑:这显然不适用于iOS 6.当然,这不应该让人感到惊讶。但是,据我所知,委托方法的行为相同,因此OP的问题仍然存在。我没有寻找更新的解决方案。
答案 1 :(得分:1)
讨厌发布这些解决方案,但是。 MKMapView本身有很多子视图。 在它的子视图层次结构中,有一个类MKTiledView的视图,它将TiledLayer作为图层。
因此,实际上,您无法以“正常”方式解决渲染通知。
Tiled图层通过不断调用-drawLayer来呈现它的内容:inContext:它的委托方法,MKTiledView是。这些调用可以在不同的线程中同时执行。
您没有收到MKMapView的规范(更新),因为它没有自行更新。只有它的基础内容正在更新。
因此。总有更好的解决方案存在。 我的解决方案取决于视图层次结构和方法的混合。 这取决于你,使用与否。
创建类别方法,我们将“更新通知”发布到需要更新的自定义视图
@implementation UIView (Custom)
- (void)drawCustomLayer:(CALayer *)layer inContext:(CGContextRef)ctx {
NSLog(@"Need to draw custom layer :%@ in context %@, Thread: %@", layer, ctx, [NSThread currentThread]);
// Calling old method
[self drawCustomLayer:layer inContext:ctx];
}
@end
//将MKTiledView的方法实现交换到我们的自定义实现
#import <objc/runtime.h>
Class tileViewclass = NSClassFromString(@"MKMapTileView");
Class viewClass = NSClassFromString(@"UIView");
SEL originalSelector = @selector(drawLayer:inContext:);
SEL newSelector = @selector(drawCustomLayer:inContext:);
Method origMethod = class_getInstanceMethod(tileViewclass, originalSelector);
Method newMethod = class_getInstanceMethod(viewClass, newSelector);
method_exchangeImplementations(origMethod, newMethod);
仍在寻找更好的解决方案。
答案 2 :(得分:-1)
MKMapView有许多重绘的子视图。很难找到哪个视图或图层...
或者您可以尝试查找某些MKMapView属性已更改。您可以使用Key Value Observing(KVO)机制来完成此操作。 http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/KeyValueObserving/KeyValueObserving.html
EG。 (属性可以更改为您需要的任何内容)
[myMapView addObserver:self forKeyPath:@"region" options:NSKeyValueObservingOptionNew context:nil];
[myMapView addObserver:self forKeyPath:@"centerCoordinate" options:NSKeyValueObservingOptionNew context:nil];
您应该实施observeValueForKeyPath:ofObject:change:context:
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
{
// Do something that you want with keyPath;
}
每当mapView为您定义的每个属性都有新值时,将触发此方法。