iOS高德地圖定位.自定義標注.搜索.分類展示(排版)


 

一.先前准備

4.0 .jpg
4.0 .jpg

這就是公司的需求,上面欄目點擊刷新地圖標注,類目二根據類目一的變化而變化,標注可點擊進個人資料,點擊下單也可跳轉.

1.1).sdk下載http://lbs.amap.com/api/ios-sdk/summary/,推薦pod導入,其他添加依賴庫請參考官方文檔

1.0.png
1.0.png

1.2).在用到的vc導入,還有遵循協議<MAMapViewDelegate>,這里還要謝謝簡書一位仁兄,因為最后兩個文件我也是參考他的

1.1.png
1.1.png

二.上代碼 2.1).先定義一些需要用到的小寶寶

1.2.png
1.2.png

2.2).viewDidLoad里的幾個方法

1.4.png
1.4.png

實現這幾個方法:

2.2.1).- (void)initMapView

{

[AMapServices sharedServices].apiKey = @"你的key";

self.mapView = [[MAMapView alloc] initWithFrame:CGRectMake(0, 64+60, CGRectGetWidth(self.view.bounds), self.view.bounds.size.height-64-60)];
self.mapView.delegate = self;
self.mapView.showsCompass = NO;
self.mapView.showsScale = NO;
self.mapView.zoomLevel = 17;
self.mapView.showsUserLocation = YES;

[self.view addSubview:self.mapView];
self.isLocated = NO;
}

2.2.2).- (void)initSearch

{

self.searchPage = 1;

//c6375c001facf8ec415c6b087ba4a364

[AMapServices sharedServices].apiKey = @"你的key";

self.search = [[AMapSearchAPI alloc] init];

}

2.2.3).- (void)initRedWaterView

{

self.redWaterView = [[UIView alloc]initWithFrame:CGRectMake((kScreenWidth-60)/2, self.mapView.bounds.size.height/2-50, 60, 60)];

self.redWaterView.center = CGPointMake(CGRectGetWidth(self.view.bounds) / 2, CGRectGetHeight(self.mapView.bounds) / 2 - CGRectGetHeight(self.redWaterView.bounds) / 2);

self.redWaterView.backgroundColor = kAppClearColor;

UIImage *image = [UIImage imageNamed:@"wateRedBlank@2x.png"];

UIImageView *ImageV = [[UIImageView alloc]initWithFrame:CGRectMake((60-image.size.width)/2, 30, image.size.width, image.size.height)];

ImageV.image = image;

UIButton *BTn = [UIButton buttonWithType:UIButtonTypeCustom];

BTn.frame = CGRectMake(0, 0, 60, 25);

BTn.layer.cornerRadius = 10;

BTn.layer.masksToBounds = YES;

BTn.backgroundColor = kAppGoodColor;

[BTn setTitle:@"點擊下單" forState:UIControlStateNormal];

[BTn setTitleColor:kAppWhiteColor forState:UIControlStateNormal];

BTn.titleLabel.font = [UIFont systemFontOfSize:13];

[BTn addTarget:self action:@selector(AddOrder:) forControlEvents:UIControlEventTouchUpInside];

[self.redWaterView addSubview:BTn];

[self.redWaterView addSubview:ImageV];

[self.view addSubview:self.redWaterView];

}

2.2.4).- (void)initLocationButton //這是左下角的定位按鈕

{

self.imageLocated = [UIImage imageNamed:@"gpssearchbutton@2x.png"];

self.imageNotLocate = [UIImage imageNamed:@"gpsnormal@2x.png"];

self.locationBtn = [[UIButton alloc] initWithFrame:CGRectMake(CGRectGetWidth(self.mapView.bounds)*0.8+10, CGRectGetHeight(self.mapView.bounds)*0.8+64, 40, 40)];

self.locationBtn.autoresizingMask = UIViewAutoresizingFlexibleTopMargin;

self.locationBtn.backgroundColor = [UIColor colorWithRed:239.0/255 green:239.0/255 blue:239.0/255 alpha:1];

self.locationBtn.layer.cornerRadius = 3;

[self.locationBtn addTarget:self action:@selector(actionLocation) forControlEvents:UIControlEventTouchUpInside];

[self.locationBtn setImage:self.imageNotLocate forState:UIControlStateNormal];

[self.view addSubview:self.locationBtn];

}

2.3).一些協議方法和自己定義的方法

/* 移動窗口彈一下的動畫 */

- (void)redWaterAnimimate

{

[UIView animateWithDuration:0.5

delay:0

options:UIViewAnimationOptionCurveEaseOut

animations:^{

CGPoint center = self.redWaterView.center;

center.y -= 20;

[self.redWaterView setCenter:center];}

completion:nil];

[UIView animateWithDuration:0.45

delay:0

options:UIViewAnimationOptionCurveEaseIn

animations:^{

CGPoint center = self.redWaterView.center;

center.y += 20;

[self.redWaterView setCenter:center];}

completion:nil];

}

#pragma mark - Utility

/* 根據中心點坐標來搜周邊的POI. */

- (void)searchPoiByCenterCoordinate:(CLLocationCoordinate2D )coord

{

AMapPOIAroundSearchRequest*request = [[AMapPOIAroundSearchRequest alloc] init];

request.location = [AMapGeoPoint locationWithLatitude:coord.latitude  longitude:coord.longitude];

request.radius  = 500;//自己定義搜索半徑

request.sortrule = 1;

request.page    = self.searchPage;

[self.search AMapPOIAroundSearch:request];

}

- (void)searchReGeocodeWithCoordinate:(CLLocationCoordinate2D)coordinate

{

AMapReGeocodeSearchRequest *regeo = [[AMapReGeocodeSearchRequest alloc] init];

regeo.location = [AMapGeoPoint locationWithLatitude:coordinate.latitude longitude:coordinate.longitude];

regeo.requireExtension = YES;

[self.search AMapReGoecodeSearch:regeo];

}

#pragma mark - MapViewDelegate

- (void)mapView:(MAMapView *)mapView regionDidChangeAnimated:(BOOL)animated

{

if (!self.isMapViewRegionChangedFromTableView && self.mapView.userTrackingMode == MAUserTrackingModeNone)

{

[self searchReGeocodeWithCoordinate:self.mapView.centerCoordinate];

[self searchPoiByCenterCoordinate:self.mapView.centerCoordinate];

self.searchPage = 1;

[self redWaterAnimimate];

}

self.isMapViewRegionChangedFromTableView = NO;

}

#pragma mark - userLocation

- (void)mapView:(MAMapView *)mapView didUpdateUserLocation:(MAUserLocation *)userLocation updatingLocation:(BOOL)updatingLocation

{

if(!updatingLocation)

return ;

if (userLocation.location.horizontalAccuracy < 0)

{

return ;

}

// only the first locate used.

if (!self.isLocated)

{

self.isLocated = YES;

[self.mapView setCenterCoordinate:CLLocationCoordinate2DMake(userLocation.location.coordinate.latitude, userLocation.location.coordinate.longitude)];

NSLog(@"latitude : %f,longitude: %f",userLocation.location.coordinate.latitude, userLocation.location.coordinate.longitude);

}

}

- (void)mapView:(MAMapView *)mapView  didChangeUserTrackingMode:(MAUserTrackingMode)mode animated:(BOOL)animated

{

if (mode == MAUserTrackingModeNone)

{

[self.locationBtn setImage:self.imageNotLocate forState:UIControlStateNormal];

}

else

{

[self.locationBtn setImage:self.imageLocated forState:UIControlStateNormal];

}

}

- (void)mapView:(MAMapView *)mapView didFailToLocateUserWithError:(NSError *)error

{

//NSLog(@"error = %@",error);

}

#pragma mark - Handle Action

- (void)actionLocation

{

if (self.mapView.userTrackingMode == MAUserTrackingModeFollow)

{

[self.mapView setUserTrackingMode:MAUserTrackingModeNone animated:YES];

}

else

{

self.searchPage = 1;

[self.mapView setCenterCoordinate:self.mapView.userLocation.coordinate animated:YES];

dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 0.5 * NSEC_PER_SEC), dispatch_get_main_queue(), ^{

[self.mapView setUserTrackingMode:MAUserTrackingModeFollow animated:YES];

});

}

}

2.4).獲取數據以及生成UI

-(void)createData

{根據接口獲取到類目數據 生成UI  [self createUI]}

實現這個方法,就是上面類目UI的實現

-(void)createUI

{

FbwManager *Manger = [FbwManager shareManager];

for (NSDictionary *dic in _TwoDataArray[0]) {//數據已經獲取到

[_DataArray2 addObject:dic[@"name"]];

[_DataArray2Id addObject:dic[@"id"]];

}

__weak __typeof(self)weakSelf = self;

UIScrollView *topScrollView = [[UIScrollView alloc]init];

[self.view addSubview:topScrollView];

[topScrollView mas_makeConstraints:^(MASConstraintMaker *make) {

make.top.equalTo(@64);

make.left.equalTo(weakSelf.view);

make.right.equalTo(@0);//make.right.equalTo(@-30);

make.height.equalTo(@30);//make.height.equalTo(@30);

}];

topScrollView.backgroundColor = kAppGoodColor;

topScrollView.contentSize = CGSizeMake(_OneDataArray.count * (kScreenWidth-30)/4.f, 0);

UIButton *_lastBtn;

NSInteger i = 0;

for (NSString *title in _OneDataArray) {

UIButton *btn = [UIButton buttonWithType:UIButtonTypeCustom];

btn.frame = CGRectMake(_lastBtn ? _lastBtn.right : 0, 0, (kScreenWidth-30)/4.f, 30);

[topScrollView addSubview:btn];

//        [btn mas_makeConstraints:^(MASConstraintMaker *make) {

//            make.left.equalTo(_lastBtn ? _lastBtn.mas_right : @0);

//            make.top.bottom.equalTo(topScrollView);

//            make.width.equalTo(@((kScreenWidth-30)/4.f));

//        }];

btn.backgroundColor = kAppClearColor;

[btn setTitleColor:kAppWhiteColor forState:UIControlStateNormal];

[btn setTitle:title forState:UIControlStateNormal];

btn.titleLabel.font = [UIFont boldSystemFontOfSize:14];

[btn addTarget:self action:@selector(btnAction:) forControlEvents:UIControlEventTouchUpInside];

_lastBtn = btn;

i++;

btn.tag = 10+i;

if (btn.tag == 11) {

}}

UIScrollView *bottomScrollView = [[UIScrollView alloc]init];

[self.view addSubview:bottomScrollView];

[bottomScrollView mas_makeConstraints:^(MASConstraintMaker *make) {

make.top.equalTo(topScrollView.mas_bottom);

make.left.right.equalTo(weakSelf.view);

make.height.equalTo(@30);

}];

bottomScrollView.backgroundColor = [UIColor colorWithRed:230/255.f green:230/255.f blue:230/255.f alpha:1];

bottomScrollView.tag = 101;

[self createBottomViewWithArray:_DataArray2];//類目二根據類目一生成

[self createMapAnni];//生成標注

if (_DataArray2.count != 0) {

Manger.YueOrderName = _DataArray2[0];

}

if (_DataArray2Id.count != 0) {

Manger.YueOrderId = _DataArray2Id[0];

}

}

2.4.1).標注的生成以及實現過程

-(void)createMapAnni

{
  //根據你的定位坐標和設置的搜索半徑以及類目的ID獲取到該類目下的用戶 獲取到數據 調用[self initAnnotations];
}

-(void)initAnnotations{

NSMutableArray *coordinates = [NSMutableArray array];}

for (int i = 0; i < _dataArray.count; i++)

{

ThirdMcModel *model = _dataArray[i];

//            MAPointAnnotation *a1 = [[MAPointAnnotation alloc] init];

//            a1.coordinate = CLLocationCoordinate2DMake([model.UserX doubleValue],[model.UserY doubleValue]);

//            [coordinates addObject:a1];

HQMCustomAnnotation *femaleAnn = [[HQMCustomAnnotation alloc] init];//此方法參考了一位簡書的同仁 很好用,下面會給該文件的.h .m

femaleAnn.type = CustomAnnotationTypeFemale;

femaleAnn.imagePath = model.UserPic;

femaleAnn.coordinate = CLLocationCoordinate2DMake([model.UserX doubleValue],[model.UserY doubleValue]);

[coordinates addObject:femaleAnn];

}

[self.mapView addAnnotations:coordinates];

- (MAAnnotationView *)mapView:(MAMapView *)mapView viewForAnnotation:(id)annotation//這個方法也少不了 匹配模型數據

{

if ([annotation isKindOfClass:[HQMCustomAnnotation class]]) {

HQMCustomAnnotation *cusAnnotation = (HQMCustomAnnotation *)annotation;

static NSString *cusAnnotationID = @"HQMCustomAnnotation";

HQMCustomAnnotationView *cusAnnotationView = (HQMCustomAnnotationView*)[mapView dequeueReusableAnnotationViewWithIdentifier:cusAnnotationID];

if (!cusAnnotationView) {

cusAnnotationView = [[HQMCustomAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:cusAnnotationID];

}

cusAnnotationView.annotation = cusAnnotation;

//        cusAnnotationView.tag = i++;

return cusAnnotationView;

}

return nil;

}

2.4.2)根據點擊類目一類目二的實現.

-(void)createBottomViewWithArray:(NSArray *)array

{

UIScrollView *bottomScrollView = [self.view viewWithTag:101];

for (UIView *subView in bottomScrollView.subviews) {

[subView removeFromSuperview];

}

bottomScrollView.contentSize = CGSizeMake(array.count * (kScreenWidth-30)/6.f, 0);

UIButton *_last1Btn;

NSInteger i = 0;

for (NSString *title in array) {

UIButton *btn = [UIButton buttonWithType:UIButtonTypeCustom];

btn.frame = CGRectMake(_last1Btn ? _last1Btn.right : 0, 0, (kScreenWidth-30)/6.f, 30);

[bottomScrollView addSubview:btn];

//        [btn mas_makeConstraints:^(MASConstraintMaker *make) {

//            make.left.equalTo(_lastBtn ? _lastBtn.mas_right : @0);

//            make.top.bottom.equalTo(topScrollView);

//            make.width.equalTo(@((kScreenWidth-30)/4.f));

//        }];

btn.backgroundColor = kAppClearColor;

[btn setTitle:title forState:UIControlStateNormal];

//        [topScrollView addSubview:btn];

btn.titleLabel.font = [UIFont boldSystemFontOfSize:12];

//        [btn setTitleColor:[UIColor colorWithRed:0.3 green:0.3 blue:0.3 alpha:1] forState:UIControlStateNormal];

[btn setTitleColor:kAppBlackColor forState:UIControlStateNormal];

[btn addTarget:self action:@selector(btnAction1:) forControlEvents:UIControlEventTouchUpInside];

_last1Btn = btn;

i++;

btn.tag = 40+i;

if (btn.tag == 41) {

[btn setTitleColor:kAppGoodColor forState:UIControlStateNormal];

self.selectButton = btn;

}

}

}

2.5).點擊類目一以及類目二的item

-(void)btnAction:(UIButton *)tb

{

[_DataArray2 removeAllObjects];

[_DataArray2Id removeAllObjects];

for (NSDictionary *dic in _TwoDataArray[tb.tag-11]) {

if (NotNilAndNull(dic[@"name"])) {

[_DataArray2 addObject:dic[@"name"]];

}

if (NotNilAndNull(dic[@"id"])) {

[_DataArray2Id addObject:dic[@"id"]];

}

}

[self createBottomViewWithArray:_DataArray2];

}

.//點擊類目二item

-(void)btnAction1:(UIButton *)tb

{

//    NSLog(@"按鈕%ld",tb.tag);

if(self.selectButton == tb) {

//上次點擊過的按鈕,不做處理

} else{

//本次點擊的按鈕設為紅色

[tb setTitleColor:kAppGoodColor forState:UIControlStateNormal];

//將上次點擊過的按鈕設為黑色

[self.selectButton setTitleColor:kAppBlackColor forState:UIControlStateNormal];

}

self.selectButton = tb;

[self.mapView removeOverlays:self.mapView.overlays];

[self.mapView removeAnnotations:self.mapView.annotations];

//跟之前的生成標注一樣 移除數據源 再次重新請求此類目下的用戶信息

}

2.6).最后就是點擊標注進入信息 根據標注的位置和用戶的位置進行判斷

- (void)mapView:(MAMapView *)mapView didSelectAnnotationView:(MAAnnotationView *)view
{
// clickLocation 位置信息

CLLocationCoordinate2D clickLocation = view.annotation.coordinate;

for (int i = 0; i < _dataArray.count; ++i)

{

ThirdMcModel *Model = _dataArray[i];

//        NSLog(@"我你那么 %f  %f",[Model.UserX doubleValue],[Model.UserY doubleValue]);

if ([Model.UserX doubleValue] == clickLocation.latitude && [Model.UserY doubleValue] == clickLocation.longitude){

PersonalDataVC *person = [[PersonalDataVC alloc]init];

[self.navigationController pushViewController:person animated:YES];

   }
  }
}

2.7).最后上兩張做好的效果圖吧 上面的demo夠用了

1.5.jpg
1.5.jpg
1.6.jpg
1.6.jpg

2.8).帶HQMCustomAnnotation.h .m 和
HQMCustomAnnotationView.h.m

2.8.1)HQMCustomAnnotation.h

#import<MAMapKit/MAMapKit.h>

typedef NS_ENUM(NSUInteger, CustomAnnotationType){

CustomAnnotationTypeMe = 1,

CustomAnnotationTypeFemale,

CustomAnnotationTypeMale,

};

@interface HQMCustomAnnotation : MAPointAnnotation

@property (nonatomic, assign) CustomAnnotationType type;

@property (nonatomic, assign) NSInteger number;

@property (nonatomic, copy)  NSString *imagePath;

@end

2.8.2)HQMCustomAnnotation.m

#import "HQMCustomAnnotation.h"

@implementation HQMCustomAnnotation

@end

2.8.3)HQMCustomAnnotationView.h

#import<MAMapKit/MAMapKit.h>

@class HQMCustomAnnotation;@interface HQMCustomAnnotationView : MAAnnotationView
//一定要重寫,否則當滑動地圖,annotation出現和消失時候會出現數據混亂
- (void)setAnnotation:(id)annotation;
@end

2.8.4)HQMCustomAnnotationView.m

import "HQMCustomAnnotationView.h"

#import "HQMCustomAnnotation.h"

@interface HQMCustomAnnotationView()

@property (nonatomic, strong) UIImageView *backgroundImageView;

@property (nonatomic, strong) UIImageView *avatarImageView;

@property (nonatomic, strong) UIImageView *dotImageView;

@property (nonatomic, assign) NSInteger number;

@end
@implementation HQMCustomAnnotationView

#pragma mark - Life Cycle

- (void)dealloc {    self.backgroundImageView = nil;    self.avatarImageView = nil;    self.dotImageView = nil;}

- (id)initWithAnnotation:(id)annotation reuseIdentifier:(NSString *)reuseIdentifier {    HQMCustomAnnotation *ann = (HQMCustomAnnotation *)annotation;    self = [super initWithAnnotation:ann reuseIdentifier:reuseIdentifier];    if (self) {        self.backgroundColor = [UIColor clearColor];        [self initializeAnnotation:ann];    }        return self;}

- (void)initializeAnnotation:(HQMCustomAnnotation *)ann {    [self setupAnnotation:ann];}- (void)setAnnotation:(id)annotation {

[super setAnnotation:annotation];

HQMCustomAnnotation *ann = (HQMCustomAnnotation *)self.annotation;

//當annotation滑出地圖時候,即ann為nil時,不設置(否則由於枚舉的類型會執行不該執行的方法),只有annotation在地圖范圍內出現時才設置,可以打斷點調試

if (ann) {
   [self setupAnnotation:ann];
  }
}


- (void)setupAnnotation:(HQMCustomAnnotation *)ann {

NSString *mask = @"";

CGRect frame = CGRectZero;

switch (ann.type) {

case CustomAnnotationTypeMe: {//我的頭像背景

frame = CGRectMake(0, 0, 48., 60.);

mask = @"xh_dq_zb_bg.png";

break;

}

case CustomAnnotationTypeFemale: {

frame = CGRectMake(0, 0, 44., 44.);

//            mask = @"xh_zb_red_ic.png";

break;
}

case CustomAnnotationTypeMale: {

frame = CGRectMake(0, 0, 34., 46.);
mask = @"xh_zb_ic.png";
break;
}
}

self.bounds = frame;

self.centerOffset = CGPointMake(0, -self.bounds.size.height*0.5);

//設置背景圖片

self.backgroundImageView.image = [UIImage imageNamed:mask];

self.backgroundImageView.frame = self.bounds;

//設置頭像圖片

self.avatarImageView.frame = CGRectMake(0, 0, self.bounds.size.width, self.bounds.size.width);

self.avatarImageView.layer.cornerRadius = (self.bounds.size.width) * 0.5;

self.avatarImageView.layer.masksToBounds = YES;

//    UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc]initWithTarget:self action:@selector(ClickImage:)];

//    [self.avatarImageView addGestureRecognizer:tap];

if (ann.type == CustomAnnotationTypeMe) {

if (!self.dotImageView) {

self.dotImageView = [[UIImageView alloc] init];

self.dotImageView.frame = CGRectMake((frame.size.width - 11)/2, frame.size.height - 8, 12, 12);

[self addSubview:self.dotImageView];

[self sendSubviewToBack:self.dotImageView];

self.dotImageView.image = [UIImage imageNamed:@"xh_yuandian_ic.png"];

}

} else {

if (self.dotImageView) {

  [self.dotImageView removeFromSuperview];

   self.dotImageView = nil;
   }
 }
 [self setupAvatarImage];
}

- (void)setupAvatarImage {

HQMCustomAnnotation *ann = (HQMCustomAnnotation *)self.annotation;

[self.avatarImageView sd_setImageWithURL:[NSURL URLWithString:[NSString stringWithFormat:@"%@%@",BASEURL,ann.imagePath]] placeholderImage:[UIImage imageNamed:@"網紅1"]];
}

- (UIImageView *)backgroundImageView {

if (!_backgroundImageView) {

_backgroundImageView = [[UIImageView alloc] init];

[self addSubview:_backgroundImageView];
}
return _backgroundImageView;
}

- (UIImageView *)avatarImageView {

if (!_avatarImageView) {

_avatarImageView = [[UIImageView alloc] init];
[self.backgroundImageView addSubview:_avatarImageView];
}
return _avatarImageView;
}
@end


作者:博文歐巴
鏈接:http://www.jianshu.com/p/26f37c72a300
來源:簡書
著作權歸作者所有。商業轉載請聯系作者獲得授權,非商業轉載請注明出處。

注意!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系我们删除。



 
粤ICP备14056181号  © 2014-2021 ITdaan.com