iOS开发之地图搜索列表显示效果实现

实现效果

如图:


image.png

需要引入 高德3D地图SDK,高德搜索SDK,高德地图基础SDK,需配置自己的高德地图AppKey和对应的Boundle id。

项目demo是用pod集成的,demo组织架构使用了MVC设计模式。自己封装了高德地图搜索管理类,拿去直接能用,用法也很简单,关于这个搜索的封装,说明在http://www.jianshu.com/p/d5a2ace2252d,里面含gitHub地址。

框架结构

image.png

AddressSelectedController是地址搜索的界面,DDLocationReGeocode作为其Model模型,DDMapView是对地图进行的一个抽离,整体采用MVC设计模式。其中DDSearchManager文件中是封装好的搜索管理类。

各个部分的职能很明确,这样子写代码你会发现很简单,看起来也不复杂,当然你如果非要在一个Controller里面即地图又有搜索等等,也行Who cares。

实现过程

AddressSelectedController.h
#import <UIKit/UIKit.h>
#import <CoreLocation/CoreLocation.h>
#import "DDLocationReGeocode.h"

/**
 回调选则的位置信息

 @param reGeocode 位置信息
 @param error 错误码
 */
typedef void(^DDLocationCompleteBlock)(DDLocationReGeocode *reGeocode, NSError *error);

@interface AddressSelectedController : UIViewController

//回调选中地址信息的block
@property (nonatomic, copy) DDLocationCompleteBlock completeBlock;

/*
 传入经纬度度,进行反地理编码
 */
@property (nonatomic) CLLocationCoordinate2D currentCoordinate;

@end

这个界面可以从外传入初始经纬度,如果传入了初始经纬度则,地图会直接移动到传入的位置处并进行附近的兴趣点搜索,如果未传入初始经纬度,则地图默认定位到用户当前位置处。

DDLocationCompleteBlock是回调你选中地址信息的block,block里面回调了DDLocationReGeocode的对象reGeocode和NSError的错误码,这里错误码没有定义,如有需要自己添加。

当然也可以使用代理进行数据回调也是可以的,都很好。

AddressSelectedController.m

实现文件中添加了地图,tableView,实现了各自的代理方法。移动地图时进行逆地理编码查询POI点,取到兴趣点后刷新列表。

DDLocationReGeocode.h

这个model里很简单就是一些数据,在MVC中Model的作用还是挺大的,这里没能全部体现出来,只是淡单纯的储存了一下数据,作为数据传输的主体。

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

@interface DDLocationReGeocode : NSObject

@property (nonatomic, copy) NSString *city;

@property (nonatomic, copy) NSString *cityCode;

@property (nonatomic, copy) NSString *name;

@property (nonatomic, copy) NSString *address;

@property (nonatomic      ) CLLocationCoordinate2D coordinate;

@end
DDMapView.h

这个DDMapView里面也很简单就一个地图,中间放了一个图片。对于地图的封装有些人用一个Manager作为地图的管理类来管理地图,我这里直接用了一个View,上面加载了一个地图来处理的,都能实现,不知道哪个方式好,大家可以自己去试试。

#import <UIKit/UIKit.h>
#import <MAMapKit/MAMapKit.h>
@class DDMapView;

@protocol DDMapViewDelegate <NSObject>

//滑动地图先执行1,再执行2

@optional
/**
 1、地图区域改变完成后会调用此接口(多次调用)

 @param ddMapView self
 @param animated 是否动画
 */
- (void)ddMapView:(DDMapView *)ddMapView regionDidChangeAnimated:(BOOL)animated;

/**
 2、地图移动结束调用此接口(多次调用)

 @param ddMapView self
 @param wasUserAction 是否用户操作的滑动行为
 */
- (void)ddMapView:(DDMapView *)ddMapView mapDidMoveByUser:(BOOL)wasUserAction;

@end


@interface DDMapView : UIView
{
    CLLocationCoordinate2D _centerCoordinate;//当前地图的中心点经纬度
}

@property (nonatomic, weak) id <DDMapViewDelegate> delegate;
//高德地图
@property (nonatomic, strong) MAMapView *mapView;
//用户当前位置
@property (nonatomic) CLLocationCoordinate2D userCoordinate;


- (instancetype)initWithFrame:(CGRect)frame delegate:(id<DDMapViewDelegate>)delegate;

/**
 设置地图中心点的坐标

 @param centerCoordinate 经纬度坐标
 @param animated 是否有动画
 */
- (void)setCenterCoordinate:(CLLocationCoordinate2D)centerCoordinate animated:(BOOL)animated;
/**
 获取地图中心点的坐标

 @return 经纬度坐标
 */
- (CLLocationCoordinate2D)centerCoordinate;

@end

这里特别说明一下为什么我将_centerCoordinate写成一个实例变量,又写了他的set、get方法,用一个@property不就搞定了吗,当然不是这样的,之所以这样写的原因是为了扩展它的set方法,添加一个参数animated,原来费这么大惊就为了这个啊,那还有其他什么的简便方法吗,知道的告诉我吧,我们互相学习。

DDMapView.m

实现文件里添加了一个地图,一个中间的图片,中间图片没做什么动画之类的,项目需要的话可以自己做,我看好多地图会做一个地图一滑动,这个图片跳动一下,当然这个也是可以的,做个简单的也还是可以的,然后下面再加个什么雷达效果什么的。

代码在最后说明里面,下载自己看看,欢迎提出意见,别忘了用之前配置你的AppKey。

最后说明

这只是一个小demo而已,根据自己项目的实际情况可以自己进行封装更多功能。我将这个小demo放在这里,如果有一起学习的可以交流https://github.com/Mexiang/AddressSearchController

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容