地圖的功能幾乎每個App都會用到. 特別是有定位功能的app,從開發(fā)到現(xiàn)在,地圖功能基本是我常用到的.我就抽空總結(jié)一下近 3年多的地圖使用經(jīng)驗.
1:關(guān)于第三方SDK無法獲取定位 狀態(tài)改變的問題
? ? ? ? 關(guān)于這個SDK的地圖的坑,我至今都沒有找到直接的解決方法, 而是采用 規(guī)避的方法解決這個問題. 由于我以前公司項目 同時 用到了百度SDK,高德導(dǎo)航(SDK),谷歌SDK.更別說 能拿到定位狀態(tài)改變了. 有時人為的關(guān)掉定位功能.更無法判斷.
我的解決方法是 用 ios 原生的 定位功能. 理由是第三方SDK都是在原生的基礎(chǔ)上封裝好的.地圖的集成我就不多說了.上代碼.
第1步:導(dǎo)入頭文件和 簽協(xié)議
第2步:初始化?
?//!定位管理
@property (nonatomic, strong) CLLocationManager *locationManager;
#pragma mark - ======================
- (CLLocationManager *)locationManager
{
if (!_locationManager)
{
_locationManager = [[CLLocationManager alloc] init];
_locationManager.delegate = self;
// 設(shè)置定位精度
_locationManager.desiredAccuracy = kCLLocationAccuracyBest;
// 定位頻率,每隔多少米定位一次
_locationManager.distanceFilter = kCLDistanceFilterNone;
}
return _locationManager;
}
再視圖加載完成這里 調(diào)用這句話.去用懶加載方式初始化 原生定位 管理器
接下來 當(dāng)你運行時,這個界面出現(xiàn)時,會走 原生的代理協(xié)議方法
在定位成功前會做一個判斷 實時定位狀態(tài)的協(xié)議方法
- (void)locationManager:(CLLocationManager *)manager didChangeAuthorizationStatus:(CLAuthorizationStatus)status
{
if(status == kCLAuthorizationStatusAuthorizedWhenInUse){
XYLLog(@"使用");
[self.locationManager startUpdatingLocation];
}else if(status == kCLAuthorizationStatusDenied){
XYLLog(@"不使用");
[self.locationManager requestWhenInUseAuthorization];
}
}
這個是手機(jī)設(shè)備采集到的 GPS做標(biāo),如果項目集成了 百度SDK 建議進(jìn)行地圖糾偏處理
- (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error{
XYLLog(@"定位失敗");
}
當(dāng)定位成功后,那到 糾偏后的經(jīng)緯度, 我們要填加 定位點,顯示出來. 原生的定位點 沒有第三方的樣式多.只有自己自定義
我上代碼:?
繼承 BMKAnnotationView ,這是自定義的, m 文件的實現(xiàn)
//? 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;}//!內(nèi)圈- (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;
}
里面還有 高級動畫的實現(xiàn)
另外 自定義的 大頭針?
注意繼承 BMKAnnotation
//? XYLPinView.h//? XYLBaiDuMap////? Created by 夏玉林 on 16/12/17.//? Copyright ? 2016年 夏玉林. All rights reserved.//#import// 引入地圖功能所有的頭文件#import//該類為標(biāo)注點的protocol摇天,提供了標(biāo)注類的基本信息函數(shù)@interface XYLPinView : NSObject/*
*? 傳入經(jīng)緯度結(jié)合體
*/
- (instancetype)initWithCoordinate:(CLLocationCoordinate2D )coordinate;
@property (nonatomic,assign) CLLocationCoordinate2D coordinate;
//標(biāo)題
@property (nonatomic,copy)NSString *title;
//副標(biāo)題
@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
/*
*? 傳入經(jīng)緯度結(jié)合體
*/
- (instancetype)initWithCoordinate:(CLLocationCoordinate2D )coordinate{
self = [super init];
if (self) {
self.coordinate = coordinate;
}
return self;
}
- (CLLocationCoordinate2D)coordinate
{
return _coordinate;
}
@end
?然后 是 調(diào)用百度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;
}
?到這里 定位點功能實現(xiàn)了. ?還是心跳的,脈沖.?