在MKMapView上添加带有模糊效果的圆圈

Mat*_*uez 13 core-graphics core-image mapkit mkmapview ios

我正在尝试在地图上的叠加层上添加模糊效果.我实际上需要在地图上的圆圈上模糊效果,我用来获得它的方法并不重要.

我有一个扩展的类,MKCircleRenderer我想在它覆盖的地图上添加模糊效果.

我正在尝试使用这种-fillPath:inContext:方法,但我对Core Graphics和Core Image的无知导致我无处可去,我真的对这个问题感到很遗憾.

我的尝试是使用CIFilter和为此我需要一个CIImage我试图从上下文创建.但是我发现没有办法创造CGBitmapContext,CGImage也不是从上下文的任何其他类.我试过的任何方法都会产生NULL而没有关于原因的进一步细节.我不记得所有我尝试过的所以我很抱歉没有指出任何相关的内容.

我的类目前实现了一个做得不多的方法:

- (instancetype)initWithOverlay:(id<MKOverlay>)overlay {
    if (self = [super initWithOverlay:overlay]) {
        self.strokeColor = [UIColor colorWithRed:0.0 green:0.0 blue:0.0 alpha:1];
        self.fillColor = [UIColor colorWithRed:0.4 green:0.2 blue:0.2 alpha:0.1];
        self.lineWidth = 1;
    }
    return self;
}
Run Code Online (Sandbox Code Playgroud)

另一种方法是使用自定义,MKAnnotation并在视图上添加模糊效果UIVisualEffectView.这种方法的难点在于缩放时增大/减小尺寸.

这应该适用于iOS 8+

编辑

在这种情况下,圆圈内部的地图应该模糊

Mat*_*uez 2

所以我最终UIVisualEffectView在覆盖层之上使用了一个。诀窍在于使用 aCADisplayLink来保持视图的位置。

下面是一些完成这项工作的代码示例(它忽略了在应用程序上实际执行此操作时应考虑的一些事情,例如删除链接、跟踪 viewDidAppear 上完成的操作必须与可能对称的工作配对在 viewWillDissapear 或其他东西上,我认为我可以使用 viewDidLoad,但在测试时是这样做的)。

#import "ViewController.h"
#import <MapKit/MapKit.h>
#import <QuartzCore/QuartzCore.h>

@interface ViewController () {
    IBOutlet MKMapView *map;
    UIView *ov;
    MKCircle *c;
    UIVisualEffectView *ev;
}

@end

@implementation ViewController

- (void)viewDidAppear:(BOOL)animated {
    [super viewDidAppear:animated];

    CLLocationCoordinate2D center = CLLocationCoordinate2DMake(40.7828647,-73.9675438);
    c = [MKCircle circleWithCenterCoordinate:center radius:1000];
    [map addOverlay:c];
    MKCoordinateSpan span = MKCoordinateSpanMake(0.07, 0.07);
    MKCoordinateRegion region = MKCoordinateRegionMake(center, span);
    region = [map regionThatFits:region];
    [map setRegion:region animated:YES];

    ov = [[UIView alloc] init];
    ov.translatesAutoresizingMaskIntoConstraints = NO;
    ov.backgroundColor = [UIColor clearColor];
    ov.clipsToBounds = YES;
    ov.layer.borderWidth = 1;
    ov.layer.borderColor = [UIColor blackColor].CGColor;
    [map addSubview:ov];

    UIBlurEffect *blur = [UIBlurEffect effectWithStyle:UIBlurEffectStyleLight];
    ev = [[UIVisualEffectView alloc] initWithEffect:blur];
    [ov addSubview:ev];

    CADisplayLink *link = [CADisplayLink displayLinkWithTarget:self selector:@selector(update:)];
    [link addToRunLoop:[NSRunLoop mainRunLoop] forMode:NSRunLoopCommonModes];
}

- (void)update:(CADisplayLink *)link {
    ov.frame = [map convertRegion:MKCoordinateRegionForMapRect(c.boundingMapRect) toRectToView:map];
    ov.layer.cornerRadius = ov.frame.size.height / 2;
    ev.frame = CGRectMake(0, 0, ov.frame.size.width, ov.frame.size.height);
}

@end
Run Code Online (Sandbox Code Playgroud)

编辑:截图