iOS开发系列--地图与定位源代码详解

2020-01-18 17:38:32王振洲

运行效果:
ios开发地图定位,ios自带地图定位开发,ios开发百度地图定位

注意:

在MapKit框架中除了MKAnnotationView之外还有一个MKPinAnnotationView,它是MKAnnotationView的子类,相比MKAnnotationView多了两个属性pinColor和animationDrop,分别用于设置大头针视图颜色和添加大头针动画。

扩展--自定义大头针弹详情视图

通过上面的示例不难看出MKAnnotationView足够强大(何况还有MKPinAnnotationView),很多信息都可以进行设置,但是唯独不能修改大头针描述详情视图(仅仅支持详情中左右视图内容)。要实现这个需求目前开发中普遍采用的思路就是:

a.点击一个大头针A时重新在A的坐标处添加另一个大头针B(注意此时将A对应的大头针视图canShowCallout设置为false)作为大头针详情模型,然后在- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>)annotation;代理方法中判断大头针类型,如果是B则重写MKAnnotationView(可以自定义一个类C继承于MKAnnotationView),返回自定义大头针视图C。

b.定义大头针视图C继承于MKAnnotationView(或者MKPinAnnotationView),在自定义大头针视图中添加自己的控件,完成自定义布局。

在使用百度地图客户端时当点击一个搜索位置时可以看到此位置的评价等信息,视图效果大概如下:ios开发地图定位,ios自带地图定位开发,ios开发百度地图定位

下面不妨试着实现一下这个效果:

大头针模型:KCAnnotation.h


//
// KCAnnotation.h
// MapKit
//
// Created by Kenshin Cui on 14/3/27.
// Copyright (c) 2014年 Kenshin Cui. All rights reserved.
//

#import <Foundation/Foundation.h>
#import <MapKit/MapKit.h>

@interface KCAnnotation : NSObject<MKAnnotation>

@property (nonatomic) CLLocationCoordinate2D coordinate;
@property (nonatomic, copy) NSString *title;
@property (nonatomic, copy) NSString *subtitle;

#pragma mark 自定义一个图片属性在创建大头针视图时使用
@property (nonatomic,strong) UIImage *image;

#pragma mark 大头针详情左侧图标
@property (nonatomic,strong) UIImage *icon;
#pragma mark 大头针详情描述 
@property (nonatomic,copy) NSString *detail;
#pragma mark 大头针右下方星级评价
@property (nonatomic,strong) UIImage *rate;

@end

弹出详情大头针模型:KCCalloutAnnotation.h


//
// KCCalloutAnnotation.h
// MapKit
//
// Created by Kenshin Cui on 14/3/27.
// Copyright (c) 2014年 Kenshin Cui. All rights reserved.
//

#import <UIKit/UIKit.h>
#import <CoreLocation/CoreLocation.h>
#import <MapKit/MapKit.h>

@interface KCCalloutAnnotation : NSObject<MKAnnotation>

@property (nonatomic) CLLocationCoordinate2D coordinate;
@property (nonatomic, copy,readonly) NSString *title;
@property (nonatomic, copy,readonly) NSString *subtitle;

#pragma mark 左侧图标
@property (nonatomic,strong) UIImage *icon;
#pragma mark 详情描述
@property (nonatomic,copy) NSString *detail;
#pragma mark 星级评价
@property (nonatomic,strong) UIImage *rate;

@end
弹出详情大头针视图:KCCalloutAnnotatonView.h

//
// KCCalloutView.h
// MapKit
//
// Created by Kenshin Cui on 14/3/27.
// Copyright (c) 2014年 Kenshin Cui. All rights reserved.
// 自定义弹出标注视图

#import <UIKit/UIKit.h>
#import <CoreLocation/CoreLocation.h>
#import <MapKit/MapKit.h>
#import "KCCalloutAnnotation.h"

@interface KCCalloutAnnotationView : MKAnnotationView

@property (nonatomic ,strong) KCCalloutAnnotation *annotation;

#pragma mark 从缓存取出标注视图
+(instancetype)calloutViewWithMapView:(MKMapView *)mapView;

@end
KCCalloutAnnotationView.m

//
// KCCalloutView.m
// MapKit
//
// Created by Kenshin Cui on 14/3/27.
// Copyright (c) 2014年 Kenshin Cui. All rights reserved.
//

#import "KCCalloutAnnotationView.h"
#define kSpacing 5
#define kDetailFontSize 12
#define kViewOffset 80

@interface KCCalloutAnnotationView(){
  UIView *_backgroundView;
  UIImageView *_iconView;
  UILabel *_detailLabel;
  UIImageView *_rateView;
}

@end

@implementation KCCalloutAnnotationView

-(instancetype)init{
  if(self=[super init]){
    [self layoutUI];
  }
  return self;
}
-(instancetype)initWithFrame:(CGRect)frame{
  if (self=[super initWithFrame:frame]) {
    [self layoutUI];
  }
  return self;
}

-(void)layoutUI{
  //背景
  _backgroundView=[[UIView alloc]init];
  _backgroundView.backgroundColor=[UIColor whiteColor];
  //左侧添加图标
  _iconView=[[UIImageView alloc]init];
  
  //上方详情
  _detailLabel=[[UILabel alloc]init];
  _detailLabel.lineBreakMode=NSLineBreakByWordWrapping;
  //[_text sizeToFit];
  _detailLabel.font=[UIFont systemFontOfSize:kDetailFontSize];
  
  //下方星级
  _rateView=[[UIImageView alloc]init];
  
  [self addSubview:_backgroundView];
  [self addSubview:_iconView];
  [self addSubview:_detailLabel];
  [self addSubview:_rateView];
}

+(instancetype)calloutViewWithMapView:(MKMapView *)mapView{
  static NSString *calloutKey=@"calloutKey1";
  KCCalloutAnnotationView *calloutView=(KCCalloutAnnotationView *)[mapView dequeueReusableAnnotationViewWithIdentifier:calloutKey];
  if (!calloutView) {
    calloutView=[[KCCalloutAnnotationView alloc]init];
  }
  return calloutView;
}

#pragma mark 当给大头针视图设置大头针模型时可以在此处根据模型设置视图内容
-(void)setAnnotation:(KCCalloutAnnotation *)annotation{
  [super setAnnotation:annotation];
  //根据模型调整布局
  _iconView.image=annotation.icon;
  _iconView.frame=CGRectMake(kSpacing, kSpacing, annotation.icon.size.width, annotation.icon.size.height);
  
  _detailLabel.text=annotation.detail;
  float detailWidth=150.0;
  CGSize detailSize= [annotation.detail boundingRectWithSize:CGSizeMake(detailWidth, MAXFLOAT) options:NSStringDrawingUsesLineFragmentOrigin attributes:@{NSFontAttributeName: [UIFont systemFontOfSize:kDetailFontSize]} context:nil].size;
  float detailX=CGRectGetMaxX(_iconView.frame)+kSpacing;
  _detailLabel.frame=CGRectMake(detailX, kSpacing, detailSize.width, detailSize.height);
  _rateView.image=annotation.rate;
  _rateView.frame=CGRectMake(detailX, CGRectGetMaxY(_detailLabel.frame)+kSpacing, annotation.rate.size.width, annotation.rate.size.height);
  
  float backgroundWidth=CGRectGetMaxX(_detailLabel.frame)+kSpacing;
  float backgroundHeight=_iconView.frame.size.height+2*kSpacing;
  _backgroundView.frame=CGRectMake(0, 0, backgroundWidth, backgroundHeight);
  self.bounds=CGRectMake(0, 0, backgroundWidth, backgroundHeight+kViewOffset);
  
}
@end