一蹄殃、MapKit框架使用前提
- 導(dǎo)入MapKit框架
- 導(dǎo)入MapKit的主頭文件
#import <MapKit/MapKit.h> - 如果是storyboard中用到了地圖,必須手動導(dǎo)入MapKit框架,否則會報下面的錯誤:
Terminating app due to uncaught exception 'NSInvalidUnarchiveOperationException', reason: 'Could not instantiate class named MKMapView'
- MapKit框架中所有的數(shù)據(jù)類型的前綴都是以MK開頭抖棘;MapKit有一個非常重要的UI控件:MKMapView磨总,專門用于地圖顯示介评。
二看政、追蹤顯示用戶的位置
在CoreLocation框架中,使用startUpdatingLocation方法欺栗,來定位用戶毫痕。而在MapKit框架中,設(shè)置MapView的userTrackingMode屬性跟蹤顯示用戶的當(dāng)前位置迟几。
如果在iOS8中消请,想要定位必須設(shè)置用戶主動要求用戶授權(quán),而且必須在info.plist文件中配置一項屬性才能彈出允許授權(quán)的窗口类腮。
在iOS7中臊泰,直接設(shè)置MapView的userTrackingMode屬性就可以跟蹤顯示用戶的當(dāng)前位置。
- MkUserTrackingModeNone:不跟蹤用戶的位置
- MKUserTrackingModeFollow:跟蹤并在地圖上顯示用戶的當(dāng)前位置蚜枢。
- MKUserTrackingModeFollowWithHeading:跟蹤并在地圖上顯示用戶的當(dāng)前位置缸逃,地圖會隨用戶的前進方向進行旋轉(zhuǎn)。
三厂抽、設(shè)置地圖類型
可以設(shè)置MKMapView的mapViewType(枚舉)設(shè)置地圖類型
- MKMapTypeStandard:普通地圖(默認)
- MKMapTypeSatellite:衛(wèi)星云圖
- MKMapTypeHybrid:普通地圖覆蓋與衛(wèi)星云圖之上需频。
四、MKMapView的常見代理方法
MKMapView可以設(shè)置一個代理對象筷凤,用來監(jiān)聽地圖的相關(guān)行為昭殉。
/
* 每次更新到用戶的位置就會調(diào)用(調(diào)用不頻繁, 只有位置改變才會調(diào)用)
*
* @param mapView 促發(fā)事件的控件
* @param userLocation 大頭針模型
*/
- (void)mapView:(MKMapView *)mapView didUpdateUserLocation:(MKUserLocation *)userLocation {
/*
地圖上藍色的點就稱之為大頭針
大頭針可以擁有標(biāo)題/子標(biāo)題/位置信息
大頭針上顯示什么內(nèi)容由大頭針模型確定(MKUserLocation)
*/
// 利用反地理編碼獲取位置之后設(shè)置標(biāo)題
[self.geocoder reverseGeocodeLocation:userLocation.location completionHandler:^(NSArray *placemarks, NSError *error) {
CLPlacemark *placemark = [placemarks firstObject];
NSLog(@"獲取地理位置成功 name = %@ locality = %@",placemark.name, placemark.locality);
userLocation.title = placemark.name;
userLocation.subtitle = placemark.locality;
}];
// 移動地圖到當(dāng)前用戶所在位置
// 獲取用戶當(dāng)前所在位置的經(jīng)緯度, 并且設(shè)置為地圖的中心點
[self.customMapView setCenterCoordinate:userLocation.location.coordinate
animated:YES];
// 設(shè)置地圖顯示的區(qū)域
// 獲取用戶的位置
CLLocationCoordinate2D center = userLocation.location.coordinate;
// 指定經(jīng)緯度的跨度
MKCoordinateSpan span = MKCoordinateSpanMake(0.009310,0.007812);
// 將用戶當(dāng)前的位置作為顯示區(qū)域的中心點, 并且指定需要顯示的跨度范圍
MKCoordinateRegion region = MKCoordinateRegionMake(center, span);
// 設(shè)置顯示區(qū)域
[self.customMapView setRegion:region animated:YES];
}
/**
* 地圖的區(qū)域即將改變時調(diào)用
- (void)mapView:(MKMapView *)mapView regionWillChangeAnimated:(BOOL)animated {
NSLog(@"地圖的區(qū)域即將改變時調(diào)用");
}
/**
* 地圖的區(qū)域改變完成時調(diào)用
*/
- (void)mapView:(MKMapView *)mapView regionDidChangeAnimated:(BOOL)animated {
NSLog(@"地圖的區(qū)域改變完成時調(diào)用");
NSLog(@"%f %f", self.customMapView.region.span.latitudeDelta, self.customMapView.region.span.longitudeDelta);
}
五、設(shè)置地圖的顯示
通過MKMapView的下列方法,可以設(shè)置地圖顯示的位置和區(qū)域:
- 設(shè)置地圖的中心點位置
@property (nonatomic) CLLocationCoordinate2D centerCoordinate;
-(void)setCenterCoordinate(CLLocationCoordinate2D)coordinate animated (BOOL)animated;
2.設(shè)置地圖的顯示區(qū)域
@property (nonatomic) MKCoordinateRegion region;
- (void)setRegion:(MKCoordinateRegion)region animated:(BOOL)animated;
MKCoordinateRegion是一個用來表示區(qū)域的結(jié)構(gòu)體挪丢,定義如下:
typedef struct {
CLLocationCoordinate2D center; // 區(qū)域的中心點位置
MKCoordinateSpan span; // 區(qū)域的跨度
} MKCoordinateRegion;
MKCoordinateSpan的定義:
typedef struct {
CLLocationDegrees latitudeDelta; // 緯度跨度
CLLocationDegrees longitudeDelta; // 經(jīng)度跨度
} MKCoordinateSpan;
六蹂风、大頭針
釘在某個具體位置,用來標(biāo)識這個位置上有特定的事物(比如這個位置上有家餐館)乾蓬。
- 大頭針的基本操作
添加一個大頭針
- (void)addAnnotation:(id <MKAnnotation>)annotation;
添加多個大頭針
- (void)addAnnotations:(NSArray *)annotations;
移除一個大頭針
- (void)removeAnnotation:(id<MKAnnotation>)annotation;
移除多個大頭針
- (void)removeAnnotations:(NSArray *)annotations;
注意:(id <MKAnnotation>)annotation參數(shù)是指:大頭針模型對象惠啄,用來封裝大頭針的數(shù)據(jù),比如大頭針的位置巢块、標(biāo)題、子標(biāo)題等數(shù)據(jù)巧号。
2.自定義大頭針
很多情況下族奢,需要自定義大頭針的顯示樣式,比如顯示一張圖片丹鸿。
設(shè)置MKMapView的代理越走,實現(xiàn)下面的代理方法,返回大頭針控件靠欢。
- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>)annotation;
根據(jù)傳進來的(id <MKAnnotation>)annotation參數(shù)創(chuàng)建并返回對應(yīng)的大頭針控件廊敌。
注意:
- 每次在地圖上添加一個大頭針就會調(diào)用一次。
- 如果自定義大頭針控件返回nil门怪,系統(tǒng)會按照自己默認的方式顯示骡澈。
- 自定義大頭針控件的方式和自定義表格創(chuàng)建的方式一樣,都是剛開始的時候從緩沖池中讀取掷空,如果緩存池中沒有肋殴,就會創(chuàng)建出一個新的。
- 不能把模型寫死坦弟,因為annotationView == nil調(diào)用有限护锤,每次都會從緩存池中獲取。
- 默認情況下酿傍,MKAnnotationView是不能顯示的烙懦,如果想自定義大頭針可以使用MKAnnotationView的子類MKPinAnnotationView。
- 對用戶當(dāng)前位置的大頭針特殊處理赤炒,如果不是自定義的大頭針控件氯析,就返回nil。
- 如果你是使用的MKPinAnnotationView創(chuàng)建的大頭針莺褒,那么設(shè)置的圖片無效魄鸦,因為系統(tǒng)會做一些操作,覆蓋掉我們自己的設(shè)置
- 標(biāo)識用戶位置的藍色發(fā)光圓點癣朗,它也是一個大頭針拾因,當(dāng)顯示這個大頭針時条获,也會調(diào)用代理方法气嫁,因此,需要在代理方法中分清楚(id <MKAnnotation>)annotation參數(shù)代表自定義的大頭針還是藍色發(fā)光圓點
3.MKAnnotationView
地圖上的大頭針控件是MKAnnotationView
@property (nonatomic, strong) id <MKAnnotation> annotation; // 大頭針模型
@property (nonatomic, strong) UIImage *image; // 顯示的圖片
@property (nonatomic) BOOL canShowCallout; // 是否顯示標(biāo)注
@property (nonatomic) CGPoint calloutOffset; // 標(biāo)注的偏移量
@property (strong, nonatomic) UIView *rightCalloutAccessoryView; // 標(biāo)注右邊顯示什么控件
@property (strong, nonatomic) UIView *leftCalloutAccessoryView; // 標(biāo)注左邊顯示什么控件
4.MKPinAnnotationView
MKPinAnnotationView是MKAnnotationView的子類。
MKPinAnnotationView比MKAnnotationView多了2個屬性包券。
@property (nonatomic) MKPinAnnotationColor pinColor;// 大頭針顏色
@property (nonatomic) BOOL animatesDrop; // 大頭針第一次顯示時是否從天而降