How to create custom pin annotation view

萝らか妹 提交于 2020-01-17 14:51:48

问题


I have a map I'm populating with a list of food trucks, and I'd like to implement a custom callout like the one shown below, when an annotation is selected. Currently I have the standard annotation callout implemented with a title and subtitle.

I've done some reading and am guessing it'll require a custom .xib file, but I don't really know anything about this as I only started developing for iOS as a recently. How would I go about creating this custom popup, and how can I make it perform a navigation action when clicked?

Thanks!


回答1:


Seems like you need a custom pop up view, but you don't know how to create one.

Here a sample to create a pop view like the picture you post.

This is the code, ViewController.m:

#import "ViewController.h"
#import "AnnotationView.h"

@interface ViewController ()

@end

@implementation ViewController

- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
self.view.backgroundColor = [UIColor grayColor];

AnnotationView* popUp = [[AnnotationView alloc] initWithFrame:CGRectMake(50, 100, 200, 80)];
[self.view addSubview:popUp];
}

@end

AnnotationView.m:

#import "AnnotationView.h"

@interface AnnotationView ()

@property float bottomHeight;
@property float topHeight;
@property float cornerRadius;
@property float triangleWidth;

@property UIImageView* pictureView;
@property UILabel* lbTitle;
@property UILabel* lbInfo;

@end

@implementation AnnotationView

-(id)initWithFrame:(CGRect)frame{
_bottomHeight = 20;
_topHeight = frame.size.height-_bottomHeight;
_cornerRadius = 5;
_triangleWidth = 30;

self = [super initWithFrame:frame];
self.backgroundColor = [UIColor clearColor];

self.layer.cornerRadius = _cornerRadius;
self.layer.masksToBounds = YES;

_pictureView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, _topHeight, _topHeight)];
_pictureView.image = [UIImage imageNamed:@"test.png"];
_pictureView.layer.cornerRadius = _cornerRadius;
_pictureView.layer.masksToBounds = YES;
[self addSubview:_pictureView];

float insidePadding = 10;
float lbWidth = (frame.size.width-_topHeight-2*insidePadding);

_lbTitle = [[UILabel alloc] initWithFrame:CGRectMake(_topHeight+insidePadding, 0, lbWidth, _topHeight/2)];
_lbTitle.text = @"I'm title.";
[self addSubview:_lbTitle];

_lbInfo = [[UILabel alloc] initWithFrame:CGRectMake(_topHeight+insidePadding, _topHeight/2, lbWidth, _topHeight/2)];
_lbInfo.numberOfLines = 2;
_lbInfo.font = [UIFont systemFontOfSize:10];
_lbInfo.text = @"I'm content........I'm content........";
[self addSubview:_lbInfo];

return self;
}

-(void)drawRect:(CGRect)rect{

CGContextRef con = UIGraphicsGetCurrentContext();
CGContextSetFillColorWithColor(con, [UIColor whiteColor].CGColor);
UIBezierPath* roundRect = [UIBezierPath bezierPathWithRoundedRect:CGRectMake(0, 0, rect.size.width, _topHeight) cornerRadius:_cornerRadius];
CGContextAddPath(con, roundRect.CGPath);
CGContextFillPath(con);

CGContextMoveToPoint(con, (rect.size.width-_triangleWidth)/2, _topHeight);
CGContextAddLineToPoint(con,(rect.size.width+_triangleWidth)/2, _topHeight);
CGContextAddLineToPoint(con,rect.size.width/2, rect.size.height);
CGContextClosePath(con);
CGContextFillPath(con);
}

@end

Hope it can help you. Any more question just left it here.




回答2:


First to change the pin image you need to use viewForAnnotation method of MKMapViewDelegate and set the image porperty of MKAnnotationView also to show your own view set canShowCallout property to false.

func mapView(mapView: MKMapView, viewForAnnotation annotation: MKAnnotation) -> MKAnnotationView? {
    if (annotation.isKindOfClass(MKPointAnnotation.classForCoder())) {
        var annotationView = mapView.dequeueReusableAnnotationViewWithIdentifier("AnnotationView")
        if annotationView == nil {
            annotationView = MKAnnotationView(annotation: annotation, reuseIdentifier: "AnnotationView")
        }
        else {
            annotationView!.annotation = annotation
        }
        annotationView!.image = UIImage(named: "Marker")
        annotationView!.canShowCallout = false
        return annotationView
    }
    return nil
}

Now to show your own view use didSelectAnnotationView method of MKMapViewDelegate.

    func mapView(mapView: MKMapView, didSelectAnnotationView view: MKAnnotationView) {
    mapView.deselectAnnotation(view.annotation, animated: true)

    let viewController = self.storyboard?.instantiateViewControllerWithIdentifier("AnnotationInfoViewController") as! AnnotationInfoViewController

    //If you want to show view from XIB file you can create viewController instance like this
    //let viewController = UIViewController()
    //let myView = NSBundle.mainBundle().loadNibNamed("AnnotationInfoView", owner: self, options: nil)[0] as! AnnotationInfoView
    //viewController.view = myView

    //Pass the information that you want to show
    viewController.data = passdata

    //Set the viewController for popoverPresentationController 
    viewController.modalPresentationStyle = .Popover
    viewController.preferredContentSize = CGSize(width: viewController.view.frame.size.width, height: 80)
    viewController.popoverPresentationController!.delegate = self;
    viewController.popoverPresentationController!.permittedArrowDirections = [.Up , .Down]
    viewController.popoverPresentationController!.sourceView = view.superview!
    viewController.popoverPresentationController!.sourceRect = view.frame
    self.presentViewController(viewController, animated: true, completion: nil)
}

Now to show a popup view implement adaptivePresentationStyleForPresentationController method of UIPopoverPresentationControllerDelegate.

func adaptivePresentationStyleForPresentationController(controller: UIPresentationController) -> UIModalPresentationStyle {
    return .None;
}

Note: Now if you want to handle the tap event for this popup, you can use UITapGestureRecognizer.



来源:https://stackoverflow.com/questions/38734882/how-to-create-custom-pin-annotation-view

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!