2015-10-21 6 views
13

Ich versuche, einen Unschärfe-Effekt auf einem Overlay auf einer Karte hinzuzufügen. Ich brauche eigentlich den Unschärfe-Effekt über einen Kreis auf der Karte, die Methode, die ich benutze um das zu erreichen ist nicht so wichtig.Hinzufügen eines Kreises mit Unschärfe-Effekt auf einem MKMapView

Ich habe eine Klasse, die von MKCircleRenderer erstreckt und ich wollte einen Unschärfe-Effekt über die Karte hinzufügen, die es abdeckt.

Ich habe versucht mit der -fillPath:inContext: Methode, aber meine Ignoranz über Core Graphics und Core Image führte mich nach nirgendwo und ich bin wirklich wirklich verloren in diesem Problem.

Mein Versuch war mit der CIFilter und dafür brauchte ich eine CIImage, die ich versuchte, aus dem Kontext zu erstellen. Aber ich habe keine Möglichkeit gefunden, eine CGBitmapContext, CGImage oder irgendeine andere Klasse aus dem Kontext zu erstellen. Jede Methode, die ich versuchte, ergab NULL ohne weitere Details darüber, warum. Ich kann mich nicht an alles erinnern, was ich versucht habe, und es tut mir leid, dass ich nichts darauf hingewiesen habe.

Meine Klasse implementiert derzeit ein Verfahren, die nicht wirklich viel machen:

- (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; 
} 

Eine Alternative könnte den Unschärfe-Effekt auf die Ansicht mit den UIVisualEffectView einem benutzerdefinierten MKAnnotation und fügen wird. Der schwierige Teil bei diesem Ansatz ist das Vergrößern/Verkleinern der Größe beim Zoomen.

Dieses auf iOS 8+

bearbeiten

In diesem Fall funktionieren sollte, sollte die Karte hinter der Innenseite des Kreises

+0

können Sie einen Screenshot von dem, was genau wollen Sie erreichen? Verwende die Karte mit Ausnahme eines bestimmten Kreises? Oder nur einen Kreis verschwimmen lassen? Warum ist es zoomabhängig? – luk2302

+0

Es wäre besser, wenn Sie einen Screenshot von dem zeigen, was Sie brauchen –

+0

Verwischen Sie den Kreis. Ich hätte gerne einen Bereich mit einem unscharfen Kreis. Das Gebiet sollte einen Radius von einer Viertelmeile haben, also wenn jemand hinein-/hinauszoomt, muss es seine Größe ändern. Ich werde bald ein Bild hinzufügen. –

Antwort

2

So landete ich eine UIVisualEffectView auf dem Overlay zu verbrauchen. Der Trick bestand darin, einen CADisplayLink zu verwenden, um den Blick auf Ort zu halten.

Hier ist ein Codebeispiel, das den Job erledigt (es ignoriert ein paar Dinge, die in Betracht gezogen werden sollten, wenn Sie dies in einer App tun, wie den Link entfernen und verfolgen, was mit viewDidAppear getan wird mit wahrscheinlich symmetrischem arbeiten auf viewWillDissapear oder so etwas, ich könnte ViewDidLoad ich denke, aber es so beim testen).

#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 

Edit: Screenshot

2

zu tun unscharf Es gibt zwei Möglichkeiten Das.

Einer ist einfach, Sie können einfach Bild verwenden.

Sie könnten die folgenden Bilder nützlich finden:

enter image description hereenter image description hereenter image description hereenter image description hereenter image description here

und den Code sie in viewForAnnotation zu verwenden:

- (MKAnnotationView *) mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>) annotation 
{ 
    // ... get the annotation delegate and allocate the MKAnnotationView (annView) 
     if ([annotationDelegate.type localizedCaseInsensitiveCompare:@"NeedsBluePin"] == NSOrderedSame) 
     { 
      UIImage * image = [UIImage imageNamed:@"blue_pin.png"]; 
      UIImageView *imageView = [[[UIImageView alloc] initWithImage:image] autorelease]; 
      [annView addSubview:imageView]; 
     } 
} 

Andere Verfahren haben, dass programmatisch [Kreis machen sich ]

Dieser Code kann Ihnen helfen.

import UIKit 
import AddressBook 
import AddressBookUI 
import MapKit 
import CoreLocation 
import MessageUI 
import Social 

class ViewController: UIViewController, ABPeoplePickerNavigationControllerDelegate, MFMailComposeViewControllerDelegate, MKMapViewDelegate { 

    @IBOutlet weak var name: UILabel! 
    @IBOutlet weak var email: UILabel! 
    @IBOutlet weak var photo: UIImageView! 
    @IBOutlet weak var map: MKMapView! 

    let locMan:CLLocationManager=CLLocationManager() 

    // Blurring Code 
    @IBOutlet weak var labelBackground: UIView! 
    var backgroundBlur: UIVisualEffectView! 


    @IBAction func newBFF(sender: AnyObject) { 
     let picker: ABPeoplePickerNavigationController = 
      ABPeoplePickerNavigationController() 
     picker.peoplePickerDelegate = self 
     presentViewController(picker, animated: true, completion: nil) 
    } 

    @IBAction func sendEmail(sender: AnyObject) { 
     var emailAddresses:[String]=[self.email.text!] 
     var mailComposer:MFMailComposeViewController = 
      MFMailComposeViewController() 
     mailComposer.mailComposeDelegate=self; 
     mailComposer.setToRecipients(emailAddresses) 

     presentViewController(mailComposer, animated: true, completion: nil) 
    } 

    func mailComposeController(controller: MFMailComposeViewController!, 
     didFinishWithResult result: MFMailComposeResult, error: NSError!) { 
     dismissViewControllerAnimated(true, completion: nil) 
    } 

    func peoplePickerNavigationController(peoplePicker: ABPeoplePickerNavigationController!, didSelectPerson person: ABRecord!) { 

     let friendName:String = ABRecordCopyValue(person, kABPersonFirstNameProperty).takeRetainedValue() as String as String 
     name.text=friendName 

     let friendAddressSet:ABMultiValueRef = ABRecordCopyValue(person, kABPersonAddressProperty).takeRetainedValue() 

     if ABMultiValueGetCount(friendAddressSet)>0 { 
      let friendFirstAddress: Dictionary = ABMultiValueCopyValueAtIndex(friendAddressSet, 0).takeRetainedValue() as NSDictionary 
      showAddress(friendFirstAddress) 
     } 

     let friendEmailAddresses:ABMultiValueRef = ABRecordCopyValue(person, kABPersonEmailProperty).takeRetainedValue() 

     if ABMultiValueGetCount(friendEmailAddresses)>0 { 
      let friendEmail: String = ABMultiValueCopyValueAtIndex(friendEmailAddresses, 0).takeRetainedValue() as String 
      email.text=friendEmail 
     } 

     if ABPersonHasImageData(person) { 
      photo.image = UIImage(data: ABPersonCopyImageData(person).takeRetainedValue()) 
     } 
    } 

    func showAddress(fullAddress:NSDictionary) { 
     let geocoder: CLGeocoder = CLGeocoder() 
     geocoder.geocodeAddressDictionary(fullAddress, completionHandler: 
      {(placemarks: [AnyObject]!, error: NSError!) -> Void in 
       let friendPlacemark:CLPlacemark = placemarks[0] as CLPlacemark 
       let mapRegion:MKCoordinateRegion = 
        MKCoordinateRegion(center: friendPlacemark.location.coordinate, 
         span: MKCoordinateSpanMake(0.2, 0.2)) 
       self.map.setRegion(mapRegion, animated: true) 
       let mapPlacemark: MKPlacemark = MKPlacemark(placemark: friendPlacemark) 
       self.map.addAnnotation(mapPlacemark) 
     }) 
    } 

    func mapView(aMapView: MKMapView!, 
     viewForAnnotation annotation: MKAnnotation!) -> MKAnnotationView! { 
      let pinDrop:MKPinAnnotationView = MKPinAnnotationView(annotation: annotation, reuseIdentifier: "myspot") 
      pinDrop.animatesDrop=true 
      pinDrop.canShowCallout=true 
      pinDrop.pinColor=MKPinAnnotationColor.Purple 
      return pinDrop 
    } 

    @IBAction func sendTweet(sender: AnyObject) { 
     let geocoder: CLGeocoder = CLGeocoder() 
     geocoder.reverseGeocodeLocation(map.userLocation.location, completionHandler: 
      {(placemarks: [AnyObject]!, error: NSError!) -> Void in 
       let myPlacemark:CLPlacemark = placemarks[0] as CLPlacemark 
       let tweetText:String = 
        "Hello all - I'm currently in \(myPlacemark.locality)!" 

       let tweetComposer: SLComposeViewController = 
        SLComposeViewController(forServiceType: SLServiceTypeTwitter) 

       if SLComposeViewController.isAvailableForServiceType(SLServiceTypeTwitter) { 
        tweetComposer.setInitialText(tweetText) 
        self.presentViewController(tweetComposer, animated: true, completion: nil) 
       } 
     }) 
    } 


    override func viewDidLoad() { 
     super.viewDidLoad() 
     // Do any additional setup after loading the view, typically from a nib. 
     //let locMan:CLLocationManager=CLLocationManager() 
     locMan.requestWhenInUseAuthorization() 

     let blur: UIBlurEffect = UIBlurEffect(style: UIBlurEffectStyle.Light) 
     backgroundBlur = UIVisualEffectView (effect: blur) 
     backgroundBlur.frame = labelBackground.frame 
     view.insertSubview(backgroundBlur, belowSubview: labelBackground) 
    } 

    override func didReceiveMemoryWarning() { 
     super.didReceiveMemoryWarning() 
     // Dispose of any resources that can be recreated. 
    } 

    override func preferredStatusBarStyle() -> UIStatusBarStyle { 
     return UIStatusBarStyle.LightContent 
    } 


} 
+1

Vielleicht habe ich etwas falsch ausgedrückt, aber auf der Bearbeitung wird richtig gesagt. Ich muss die Karte hinter dem Kreis verschwimmen lassen, kein Kreis, der über die Karte schwebt:/Danke trotzdem. –

+1

Auch die Ansicht für Annotation ignoriert Zoom AFAIK. Wenn ich die Ansicht vergrößern oder verkleinern, wird auf dem Bildschirm die gleiche Größe angezeigt, nicht jedoch die tatsächliche Größe auf der Karte. –