未添加遮蓋物效果:
添加遮蓋物后效果:
MKMapView上添加圖片遮蓋物的原理和添加軌跡的原理基本相同(軌跡可參考上一篇文章)矛缨,都需要自定義圖層(實(shí)現(xiàn)MKOverlay協(xié)議)和渲染器(繼承MKOverlayRenderer)碘裕。
CustomOverlay.h實(shí)現(xiàn):
#import <Foundation/Foundation.h>
#import <MapKit/MapKit.h>
@interface CustomOverlay : NSObject<MKOverlay>
@property (nonatomic, readonly) CLLocationCoordinate2D coordinate;
@property (nonatomic, readonly) MKMapRect boundingMapRect;
- (id)initWithRect:(MKMapRect)rect;
@end
CustomOverlay.m實(shí)現(xiàn):
#import "CustomOverlay.h"
@interface CustomOverlay ()
@property (nonatomic, readwrite) CLLocationCoordinate2D coordinate;
@property (nonatomic, readwrite) MKMapRect boundingMapRect;
@end
@implementation CustomOverlay
@synthesize coordinate = _coordinate;
@synthesize boundingMapRect = _boundingMapRect;
#pragma mark - Initalize
- (id)initWithRect:(MKMapRect)rect
{
if (self = [super init])
{
self.boundingMapRect = rect;
}
return self;
}
@end
CustomOverlayRenderer.h實(shí)現(xiàn):
#import <MapKit/MapKit.h>
@interface CustomOverlayRenderer : MKOverlayRenderer
@end
CustomOverlayRenderer.m實(shí)現(xiàn):(注意:繪制image要先轉(zhuǎn)CGImageRef在繪制,網(wǎng)上很多方式甚至高德提供的繪制方法都會讓cpu瞬間200%镀钓,真機(jī)調(diào)試用不到5分鐘就燙手了居灯。祭务。。)
#import "CustomOverlayRenderer.h"
#import "CustomOverlay.h"
@interface CustomOverlayRenderer ()
@property (nonatomic, strong) UIImage *image;
@end
@implementation CustomOverlayRenderer
- (id) initWithOverlay:(id<MKOverlay>)overlay{
self = [super initWithOverlay:overlay];
if (self){
self.image = [UIImage imageNamed:@"MapHiddenBG.png"];
}
return self;
}
- (void)drawMapRect:(MKMapRect)mapRect zoomScale:(MKZoomScale)zoomScale inContext:(CGContextRef)context
{
@autoreleasepool {
CustomOverlay *overlay = (CustomOverlay *)self.overlay;
if (overlay == nil)
{
NSLog(@"overlay is nil");
return;
}
MKMapRect theMapRect = [self.overlay boundingMapRect];
CGRect theRect = [self rectForMapRect:theMapRect];
// 繪制image
CGImageRef imageReference = self.image.CGImage;
CGContextScaleCTM(context, 1.0, -1.0);
CGContextTranslateCTM(context, 0.0, -theRect.size.height);
CGContextDrawImage(context, theRect, imageReference);
}
}
@end
類都實(shí)現(xiàn)了怪嫌,剩下的就是正確的在地圖上添加我們自定義的圖層:(前面那一堆都是計(jì)算軌跡在屏幕中顯示位置的义锥,也是根我項(xiàng)目相關(guān),可不用理睬)
//設(shè)置地圖在可見范圍
MKMapRect mapRect = MKMapRectNull;
for ( NSDictionary *dic in self.runningData.locationArray) {
CLLocationDegrees latitude = [dic[@"latitude"] doubleValue];
CLLocationDegrees longitude = [dic[@"longitude"] doubleValue];
CLLocationCoordinate2D coordinate = CLLocationCoordinate2DMake(latitude, longitude);
MKMapPoint annotationPoint = MKMapPointForCoordinate(coordinate);
MKMapRect pointRect = MKMapRectMake(annotationPoint.x, annotationPoint.y, 0, 0);
if (MKMapRectIsNull(mapRect)) {
mapRect = pointRect;
} else {
mapRect = MKMapRectUnion(mapRect, pointRect);
}
}
const CGFloat screenEdgeInset = kScreenEdgeInset;
UIEdgeInsets mapInset = UIEdgeInsetsMake(screenEdgeInset, screenEdgeInset, screenEdgeInset*8, screenEdgeInset);
mapRect = [self.mapView mapRectThatFits:mapRect edgePadding:mapInset];
[self.mapView setVisibleMapRect:mapRect edgePadding:mapInset animated:NO];
//添加圖片遮蓋層
self.mapHiddenImageOverlay = [[CustomOverlay alloc] initWithRect:self.mapView.visibleMapRect];
[self.mapView addOverlay:self.mapHiddenImageOverlay level:1];
添加上了岩灭,便會調(diào)用rendererForOverlay這個(gè)代理方法:(viewForOverlay別實(shí)現(xiàn)這個(gè)了拌倍,這個(gè)方法已經(jīng)標(biāo)注ios7以后會隨時(shí)銷毀,再信蘋果一次噪径,即便很多標(biāo)注銷毀的方法到今天為止也沒有幾個(gè)真正銷毀的)
#pragma mark -
#pragma mark - MKMapView Delegate
- (MKOverlayRenderer *)mapView:(MKMapView *)mapView rendererForOverlay:(id <MKOverlay>)overlay{
if([overlay isKindOfClass:[CustomOverlay class]]){
//遮擋地圖圖片
CustomOverlayRenderer *renderer = [[CustomOverlayRenderer alloc] initWithOverlay:overlay];
return renderer;
}
return nil;
}
到此柱恤,地圖上圖片遮蓋物的功能已經(jīng)實(shí)現(xiàn)了,但美中不足的是CustomOverlayRenderer中drawMapRect是按順序加載瓦礫找爱,也就是一塊一塊繪制梗顺,性能不好的手機(jī)上瓦礫的加載效果還是很明顯的,暫時(shí)還沒找到一次性繪制整張圖片的方法缴允,求指點(diǎn)~