地图的功能几乎每个App都会用到. 特别是有定位功能的app,从开发到现在,地图功能基本是我常用到的.我就抽空总结一下近 3年多的地图使用经验.
1:关于第三方SDK无法获取定位 状态改变的问题
关于这个SDK的地图的坑,我至今都没有找到直接的解决方法, 而是采用 规避的方法解决这个问题. 由于我以前公司项目 同时 用到了百度SDK,高德导航(SDK),谷歌SDK.更别说 能拿到定位状态改变了. 有时人为的关掉定位功能.更无法判断.
我的解决方法是 用 ios 原生的 定位功能. 理由是第三方SDK都是在原生的基础上封装好的.地图的集成我就不多说了.上代码.
第1步:导入头文件和 签协议
第2步:初始化
//!定位管理
@property (nonatomic, strong) CLLocationManager *locationManager;
#pragma mark - ======================
- (CLLocationManager *)locationManager
{
if (!_locationManager)
{
_locationManager = [[CLLocationManager alloc] init];
_locationManager.delegate = self;
// 设置定位精度
_locationManager.desiredAccuracy = kCLLocationAccuracyBest;
// 定位频率,每隔多少米定位一次
_locationManager.distanceFilter = kCLDistanceFilterNone;
}
return _locationManager;
}
再视图加载完成这里 调用这句话.去用懒加载方式初始化 原生定位 管理器
接下来 当你运行时,这个界面出现时,会走 原生的代理协议方法
在定位成功前会做一个判断 实时定位状态的协议方法
- (void)locationManager:(CLLocationManager *)manager didChangeAuthorizationStatus:(CLAuthorizationStatus)status
{
if(status == kCLAuthorizationStatusAuthorizedWhenInUse){
XYLLog(@"使用");
[self.locationManager startUpdatingLocation];
}else if(status == kCLAuthorizationStatusDenied){
XYLLog(@"不使用");
[self.locationManager requestWhenInUseAuthorization];
}
}
这个是手机设备采集到的 GPS做标,如果项目集成了 百度SDK 建议进行地图纠偏处理
- (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error{
XYLLog(@"定位失败");
}
当定位成功后,那到 纠偏后的经纬度, 我们要填加 定位点,显示出来. 原生的定位点 没有第三方的样式多.只有自己自定义
我上代码:
继承 BMKAnnotationView ,这是自定义的, m 文件的实现
// XYLFenceMapAnnotationView.m// XYLBaiduMap2017//// Created by 夏玉林 on 17/2/16.// Copyright © 2017年 夏玉林. All rights reserved.//#import "XYLFenceMapAnnotationView.h"@interface XYLFenceMapAnnotationView()@property (nonatomic, strong) CALayer *colorDotLayer;@property (nonatomic, strong) CALayer *outerDotLayer;@end@implementation XYLFenceMapAnnotationView//!外圈- (CALayer*)outerDotLayer { if(!_outerDotLayer) { _outerDotLayer = [CALayer layer]; _outerDotLayer.bounds = self.bounds; _outerDotLayer.contents = (id)[self circleImageWithColor:self.outerColor height:self.bounds.size.height].CGImage; _outerDotLayer.position = CGPointMake(self.bounds.size.width/2, self.bounds.size.height/2); _outerDotLayer.contentsGravity = kCAGravityCenter; _outerDotLayer.contentsScale = [UIScreen mainScreen].scale; _outerDotLayer.shadowColor = [UIColor blackColor].CGColor; _outerDotLayer.shadowOffset = CGSizeMake(0, 2); _outerDotLayer.shadowRadius = 3; _outerDotLayer.shadowOpacity = 0.3; _outerDotLayer.shouldRasterize = YES; _outerDotLayer.rasterizationScale = [UIScreen mainScreen].scale; } return _outerDotLayer;}//!内圈- (CALayer*)colorDotLayer{ if(!_colorDotLayer) { _colorDotLayer = [CALayer layer]; CGFloat width = self.bounds.size.width-6; _colorDotLayer.bounds = CGRectMake(0, 0, width, width); _colorDotLayer.allowsGroupOpacity = YES; _colorDotLayer.backgroundColor = self.annotationColor.CGColor; _colorDotLayer.cornerRadius = width/2; _colorDotLayer.position = CGPointMake(self.bounds.size.width/2, self.bounds.size.height/2); dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^(void) { if(self.delayBetweenPulseCycles != INFINITY) { CAMediaTimingFunction *defaultCurve = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionDefault]; CAAnimationGroup *animationGroup = [CAAnimationGroup animation]; animationGroup.duration = self.pulseAnimationDuration; animationGroup.repeatCount = INFINITY; animationGroup.removedOnCompletion = NO; animationGroup.autoreverses = YES; animationGroup.timingFunction = defaultCurve; animationGroup.speed = 1; animationGroup.fillMode = kCAFillModeBoth; CABasicAnimation *pulseAnimation = [CABasicAnimation animationWithKeyPath:@"transform.scale.xy"]; pulseAnimation.fromValue = @0.8; pulseAnimation.toValue = @1; pulseAnimation.duration = self.pulseAnimationDuration; CABasicAnimation *opacityAnimation = [CABasicAnimation animationWithKeyPath:@"opacity"]; opacityAnimation.fromValue = @0.8; opacityAnimation.toValue = @1; opacityAnimation.duration = self.pulseAnimationDuration; animationGroup.animations = @[pulseAnimation, opacityAnimation]; dispatch_async(dispatch_get_main_queue(), ^(void) { [_colorDotLayer addAnimation:animationGroup forKey:@"pulse"]; }); } }); } return _colorDotLayer;}#pragma mark - =====================UIView方法====================- (id)initWithAnnotation:(id)annotation reuseIdentifier:(NSString *)reuseIdentifier
{
self = [super initWithAnnotation:annotation reuseIdentifier:reuseIdentifier];
if (self)
{
#pragma mark============在这里修改定位点的 frame===============
self.bounds = CGRectMake(0, 0, 22, 22);
self.pulseAnimationDuration = 0;
self.delayBetweenPulseCycles = 0;
self.annotationColor = [UIColor colorWithRed:0.000 green:0.478 blue:1.000 alpha:1];
self.outerColor = [UIColor whiteColor];
}
return self;
}
- (void)willMoveToSuperview:(UIView *)newSuperview
{
if (newSuperview)
[self reloadLayers];
}
- (void)reloadLayers
{
[_outerDotLayer removeFromSuperlayer];
_outerDotLayer = nil;
[self.layer addSublayer:self.outerDotLayer];
[_colorDotLayer removeFromSuperlayer];
_colorDotLayer = nil;
[self.layer addSublayer:self.colorDotLayer];
}
- (UIImage*)circleImageWithColor:(UIColor*)color height:(float)height {
UIGraphicsBeginImageContextWithOptions(CGSizeMake(height, height), NO, 0);
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
UIBezierPath* fillPath = [UIBezierPath bezierPathWithOvalInRect:CGRectMake(0, 0, height, height)];
[color setFill];
[fillPath fill];
UIImage *dotImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
CGColorSpaceRelease(colorSpace);
return dotImage;
}
里面还有 高级动画的实现
另外 自定义的 大头针
注意继承 BMKAnnotation
// XYLPinView.h// XYLBaiDuMap//// Created by 夏玉林 on 16/12/17.// Copyright © 2016年 夏玉林. All rights reserved.//#import// 引入地图功能所有的头文件#import//该类为标注点的protocol,提供了标注类的基本信息函数@interface XYLPinView : NSObject/*
* 传入经纬度结合体
*/
- (instancetype)initWithCoordinate:(CLLocationCoordinate2D )coordinate;
@property (nonatomic,assign) CLLocationCoordinate2D coordinate;
//标题
@property (nonatomic,copy)NSString *title;
//副标题
@property (nonatomic,copy)NSString *subtitle;
@end
m 文件
//
// XYLPinView.m
// XYLBaiDuMap
//
// Created by 夏玉林 on 16/12/17.
// Copyright © 2016年 夏玉林. All rights reserved.
//
#import "XYLPinView.h"
@implementation XYLPinView
/*
* 传入经纬度结合体
*/
- (instancetype)initWithCoordinate:(CLLocationCoordinate2D )coordinate{
self = [super init];
if (self) {
self.coordinate = coordinate;
}
return self;
}
- (CLLocationCoordinate2D)coordinate
{
return _coordinate;
}
@end
然后 是 调用百度SDK的添加覆盖物api 接口
typeof(self) weakSelf = self;
static NSString *identifier = @"userLocation";
//定位点的显示
if ([annotation isKindOfClass:[XYLPinView class]]) {
static NSString *identifier = @"currentLocation";
XYLFenceMapAnnotationView *locationAnnotationView = (XYLFenceMapAnnotationView *)[mapView dequeueReusableAnnotationViewWithIdentifier:identifier];
if (!locationAnnotationView) {
locationAnnotationView = [[XYLFenceMapAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:identifier];
locationAnnotationView.canShowCallout = NO;
}
return locationAnnotationView;
}
return nil;
}
到这里 定位点功能实现了. 还是心跳的,脉冲.