【问题标题】:How to create custom pin annotation view如何创建自定义引脚注释视图
【发布时间】:2016-12-08 15:51:46
【问题描述】:

我有一个地图,我用食物卡车列表填充,我想在选择annotation时,我希望实现像下面所示的自定义标注。目前,我已经使用标题和副标题实现了标准注释标注。

我已经阅读了一些内容,我猜它需要一个自定义的 .xib 文件,但我对此一无所知,因为我最近才开始为 iOS 开发。我将如何创建此自定义弹出窗口,以及如何使其在单击时执行导航操作?

谢谢!

【问题讨论】:

标签: ios swift mapkit xib mkannotationview


【解决方案1】:

您似乎需要一个自定义弹出视图,但您不知道如何创建。

这里有一个示例,用于创建类似于您发布的图片的弹出视图。

这是代码,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

希望对您有所帮助。 还有什么问题就留在这里吧。

【讨论】:

  • 感谢您的回复!您(或其他用户)是否有机会将其转换为 swift?
  • 很简单的代码,你自己做吧。
【解决方案2】:

首先要更改您需要使用MKMapViewDelegateviewForAnnotation 方法并设置MKAnnotationViewimage 属性以显示您自己的视图集canShowCallout 属性为false

p>
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
}

现在要显示您自己的视图,请使用MKMapViewDelegatedidSelectAnnotationView 方法。

    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)
}

现在显示一个弹出视图,实现UIPopoverPresentationControllerDelegateadaptivePresentationStyleForPresentationController 方法。

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

注意:现在如果你想处理这个弹出窗口的点击事件,你可以使用UITapGestureRecognizer

【讨论】:

    【解决方案3】:

    我所做的是创建一个UIViewController 来显示注释的详细信息。然后选择注释时,我将UIViewController作为Popover

    func mapView(_: MKMapView, didSelect view: MKAnnotationView) {
        view.setSelected(true, animated: true)
        if let annotation = view.annotation as? BranchAnnotation {
            showDetails(from: view, with: annotation.branch)
        }
    }
    
    private func showDetails(from view: UIView, with branch: Branch) {
        let annotationDetailsPopover = AnnotationDetaisPopover(branch: branch)
        let popOver = annotationDetailsPopover.popoverPresentationController
        popOver?.sourceView = view
        popOver?.delegate = self
        present(annotationDetailsPopover, animated: true, completion: nil)
    }
    

    这样做的好处是除了对 UI 布局有很多控制之外,弹出框会根据所选注释的位置相应地显示在屏幕上(如果所选注释位于屏幕边缘弹出框被调整为从那里显示。您可以从屏幕截图中看到)

    https://i.stack.imgur.com/QUNB6.jpg

    https://i.stack.imgur.com/FCRiv.jpg

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-03-20
      • 1970-01-01
      • 2016-05-04
      • 2013-04-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多