@interface MKMapView : UIView <NSCoding>@property (nonatomic, assign) id <MKMapViewDelegate> delegate;// Changing the map type or region can cause the map to start loading map content.// The loading delegate methods will be called as map content is loaded./*enum { MKMapTypeStandard, MKMapTypeSatellite, MKMapTypeHybrid};*/@property (nonatomic) MKMapType mapType;// Region is the coordinate and span of the map.// Region may be modified to fit the aspect ratio(螢幕高寬比) of the view using regionThatFits:.@property (nonatomic) MKCoordinateRegion region;- (void)setRegion:(MKCoordinateRegion)region animated:(BOOL)animated;// centerCoordinate allows the coordinate of the region to be changed without changing the zoom level./*typedef struct { CLLocationDegrees latitude;//緯度 CLLocationDegrees longitude;//經度} CLLocationCoordinate2D;*/@property (nonatomic) CLLocationCoordinate2D centerCoordinate;- (void)setCenterCoordinate:(CLLocationCoordinate2D)coordinate animated:(BOOL)animated;// Returns a region of the aspect ratio of the map view that contains the given region, with the same center point./*Adjusts the aspect ratio of the specified region to ensure that it fits in the map view’s frame.You can use this method to normalize the region values before displaying them in the map. This methodreturns a new region that both contains the specified region and fits neatly inside the map view’s frame.*/- (MKCoordinateRegion)regionThatFits:(MKCoordinateRegion)region;// Access the visible region of the map in projected coordinates.@property (nonatomic) MKMapRect visibleMapRect;- (void)setVisibleMapRect:(MKMapRect)mapRect animated:(BOOL)animate;// Returns an MKMapRect modified to fit the aspect ratio of the map.- (MKMapRect)mapRectThatFits:(MKMapRect)mapRect;// Edge padding is the minumum padding on each side around the specified MKMapRect.- (void)setVisibleMapRect:(MKMapRect)mapRect edgePadding:(UIEdgeInsets)insets animated:(BOOL)animate;- (MKMapRect)mapRectThatFits:(MKMapRect)mapRect edgePadding:(UIEdgeInsets)insets;- (CGPoint)convertCoordinate:(CLLocationCoordinate2D)coordinate toPointToView:(UIView *)view;- (CLLocationCoordinate2D)convertPoint:(CGPoint)point toCoordinateFromView:(UIView *)view;- (CGRect)convertRegion:(MKCoordinateRegion)region toRectToView:(UIView *)view;- (MKCoordinateRegion)convertRect:(CGRect)rect toRegionFromView:(UIView *)view;// Disable user interaction from zooming or scrolling the map, or both.@property(nonatomic, getter=isZoomEnabled) BOOL zoomEnabled;@property(nonatomic, getter=isScrollEnabled) BOOL scrollEnabled;// Set to YES to add the user location annotation to the map and start updating its location@property (nonatomic) BOOL showsUserLocation;// The annotation representing the user's location@property (nonatomic, readonly) MKUserLocation *userLocation;/*enum { MKUserTrackingModeNone = 0, // the user's location is not followed MKUserTrackingModeFollow, // the map follows the user's location MKUserTrackingModeFollowWithHeading, // the map follows the user's location and heading};*/@property (nonatomic) MKUserTrackingMode userTrackingMode NS_AVAILABLE(NA, 5_0);- (void)setUserTrackingMode:(MKUserTrackingMode)mode animated:(BOOL)animated NS_AVAILABLE(NA, 5_0);// Returns YES if the user's location is displayed within the currently visible map region.@property (nonatomic, readonly, getter=isUserLocationVisible) BOOL userLocationVisible;// Annotations are models used to annotate coordinates on the map. // Implement mapView:viewForAnnotation: on MKMapViewDelegate to return the annotation view for each annotation.- (void)addAnnotation:(id <MKAnnotation>)annotation;- (void)addAnnotations:(NSArray *)annotations;- (void)removeAnnotation:(id <MKAnnotation>)annotation;- (void)removeAnnotations:(NSArray *)annotations;@property (nonatomic, readonly) NSArray *annotations;- (NSSet *)annotationsInMapRect:(MKMapRect)mapRect NS_AVAILABLE(NA, 4_2);// Currently displayed view for an annotation; returns nil if the view for the annotation isn't being displayed.- (MKAnnotationView *)viewForAnnotation:(id <MKAnnotation>)annotation;// Used by the delegate to acquire an already allocated annotation view, in lieu of allocating a new one.- (MKAnnotationView *)dequeueReusableAnnotationViewWithIdentifier:(NSString *)identifier;// Select or deselect a given annotation. Asks the delegate for the corresponding annotation view if necessary.- (void)selectAnnotation:(id <MKAnnotation>)annotation animated:(BOOL)animated;- (void)deselectAnnotation:(id <MKAnnotation>)annotation animated:(BOOL)animated;@property (nonatomic, copy) NSArray *selectedAnnotations;// annotationVisibleRect is the visible rect where the annotations views are currently displayed.// The delegate can use annotationVisibleRect when animating the adding of the annotations views in mapView:didAddAnnotationViews:@property (nonatomic, readonly) CGRect annotationVisibleRect;@end
@protocol MKMapViewDelegate <NSObject>@optional- (void)mapView:(MKMapView *)mapView regionWillChangeAnimated:(BOOL)animated;- (void)mapView:(MKMapView *)mapView regionDidChangeAnimated:(BOOL)animated;- (void)mapViewWillStartLoadingMap:(MKMapView *)mapView;- (void)mapViewDidFinishLoadingMap:(MKMapView *)mapView;- (void)mapViewDidFailLoadingMap:(MKMapView *)mapView withError:(NSError *)error;// mapView:viewForAnnotation: provides the view for each annotation.// This method may be called for all or some of the added annotations.// For MapKit provided annotations (eg. MKUserLocation) return nil to use the MapKit provided annotation view.- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>)annotation;// mapView:didAddAnnotationViews: is called after the annotation views have been added and positioned in the map.// The delegate can implement this method to animate the adding of the annotations views.// Use the current positions of the annotation views as the destinations of the animation.- (void)mapView:(MKMapView *)mapView didAddAnnotationViews:(NSArray *)views;// mapView:annotationView:calloutAccessoryControlTapped: is called when the user // taps on left & right callout accessory UIControls.- (void)mapView:(MKMapView *)mapView annotationView:(MKAnnotationView *)view calloutAccessoryControlTapped:(UIControl *)control;- (void)mapView:(MKMapView *)mapView didSelectAnnotationView:(MKAnnotationView *)view NS_AVAILABLE(NA, 4_0);- (void)mapView:(MKMapView *)mapView didDeselectAnnotationView:(MKAnnotationView *)view NS_AVAILABLE(NA, 4_0);//Tells the delegate that the map view will start tracking the user’s position.//This method is called when the value of the showsUserLocation property changes to YES.- (void)mapViewWillStartLocatingUser:(MKMapView *)mapView NS_AVAILABLE(NA, 4_0);//Tells the delegate that the map view stopped tracking the user’s location.//This method is called when the value of the showsUserLocation property changes to NO.- (void)mapViewDidStopLocatingUser:(MKMapView *)mapView NS_AVAILABLE(NA, 4_0);//Tells the delegate that the location of the user was updated./*1. a new location update is received by the map view. 2. This method is also called if the map view’s user tracking mode is set to MKUserTrackingModeFollowWithHeading and the heading changes.*/- (void)mapView:(MKMapView *)mapView didUpdateUserLocation:(MKUserLocation *)userLocation NS_AVAILABLE(NA, 4_0);- (void)mapView:(MKMapView *)mapView didFailToLocateUserWithError:(NSError *)error NS_AVAILABLE(NA, 4_0);- (void)mapView:(MKMapView *)mapView annotationView:(MKAnnotationView *)view didChangeDragState:(MKAnnotationViewDragState)newState fromOldState:(MKAnnotationViewDragState)oldState NS_AVAILABLE(NA, 4_0);- (MKOverlayView *)mapView:(MKMapView *)mapView viewForOverlay:(id <MKOverlay>)overlay NS_AVAILABLE(NA, 4_0);// Called after the provided overlay views have been added and positioned in the map.- (void)mapView:(MKMapView *)mapView didAddOverlayViews:(NSArray *)overlayViews NS_AVAILABLE(NA, 4_0);- (void)mapView:(MKMapView *)mapView didChangeUserTrackingMode:(MKUserTrackingMode)mode animated:(BOOL)animated NS_AVAILABLE(NA, 5_0);@end
1. 概述
插入MapView,設定Delegate(一般為Controller),Annotations記錄興趣位置點(AnnotationView用來顯示興趣位置點),annotation是可選的,選中的annotation會顯示callout,用來顯示資訊。
2. 設定地圖顯示類型:
mapView.mapType = MKMapTypeStandard;mapView.mapType = MKMapTypeSatellite;mapView.mapType = MKMapTypeHybrid;
3. 顯示使用者位置
設定為可以顯示使用者位置:mapView.showsUserLocation = YES; 判斷使用者當前位置是否可見(唯讀屬性):userLocationVisible 得到使用者位置座標:當userLocationVisible為YES時CLLocationCoordinate2D coords = mapView.userLocation.location.coordinate;
4.座標範圍
MKCoordinateRegion用來設定座標顯示範圍。包括兩部分:a. Center(CLLocationCoordinate2D struct,包括latitude和longitude),座標中心b. Span(MKCoordinateSpan struct,包括latitudeDelta和longitudeDelta),縮放層級//建立一個以center為中心,上下各1000米,左右各1000米得地區,但其是一個矩形,不符合MapView的橫縱比例MKCoordinateRegion viewRegion = MKCoordinateRegionMakeWithDistance(center,2000, 2000);//以上代碼建立出來一個符合MapView橫縱比例的地區MKCoordinateRegion adjustedRegion = [mapView regionThatFits:viewRegion]; //以上代碼為:最終顯示該地區[mapView setRegion:adjustedRegion animated:YES];
5. delegate
使用MapView須符合MKMapViewDelegate協議5.1、地圖載入Delegate當需要從Google伺服器取得新地圖時mapViewWillStartLoadingMap: 當成功地取得地圖後mapViewDidFinishLoadingMap: 當取得地圖失敗後(建議至少要實現此方法)mapViewDidFailLoadingMap:withError:5.2、範圍變化Delegate當手勢開始(拖拽,放大,縮小,雙擊)mapView:regionWillChangeAnimated: 當手勢結束(拖拽,放大,縮小,雙擊)mapView:regionDidChangeAnimated: 判斷座標是否在MapView顯示範圍內:CLLocationDegrees leftDegrees = mapView.region.center.longitude –(mapView.region.span.longitudeDelta / 2.0);CLLocationDegrees rightDegrees = mapView.region.center.longitude +(mapView.region.span.longitudeDelta / 2.0);CLLocationDegrees bottomDegrees = mapView.region.center.latitude –(mapView.region.span.latitudeDelta / 2.0);CLLocationDegrees topDegrees = self.region.center.latitude +(mapView.region.span.latitudeDelta / 2.0);if (leftDegrees > rightDegrees) { // Int'l Date Line in View leftDegrees = -180.0 - leftDegrees; if (coords.longitude > 0) // coords to West of Date Line coords.longitude = -180.0 - coords.longitude;}if (leftDegrees <= coords.longitude && coords.longitude <= rightDegrees && bottomDegrees <= coords.latitude && coords.latitude <= topDegrees) { // 座標在範圍內}
6.Annotation
Annotation包含兩部分:Annotation Object和Annotation ViewAnnotation Object必須符合協議MKAnnotation,包括兩個方法:title和subtitle,分別用於顯示注釋的標題和子標題。還有coordinate屬性,返回CLLocationCoordinate2D,表示Annotation的位置然後,需使用mapView:viewForAnnotation: 方法來返回MKAnnotationView或者MKAnnotationView的子類用來顯示Annotation(注意:這裡顯示的不是選中Annotation後的彈出框) 你可以子類化MKAnnotationView,然後再drawRect:方法裡面進行自己的繪製動作(這個方法很蠢)你完全可以執行個體化一個MKAnnotationView,然後更改它的image屬性,這樣很簡單。
7.添加移除Annotation
添加一個Annotation[mapView addAnnotation:annotation]; 添加一個Annotation數組[mapView addAnnotations:[NSArray arrayWithObjects:annotation1, annotation2, nil]]; 移除一個AnnotationremoveAnnotation: 移除一個Annotation數組removeAnnotations: 移除所有Annotation[mapView removeAnnotations:mapView.annotations];
8. 選中Annotation
一次只能有一個Annotation被選中,選中後會出現CallOut(浮動框)簡單的CallOut顯示Title和SubTitle,但你也可以自訂一個UIView作為CallOut(與自訂的TableViewCell一樣)可通過代碼選中Annotation:selectAnnotation:animated: 或者取消選擇:deselectAnnotation:animated:
9. 顯示Annotation
通過mapView:viewForAnnotation: 方法顯示Annotation,每在MapView中加入一個Annotation,就會調用此方法樣本(與tableView:cellForRowAtIndexPath: 很相似)- (MKAnnotationView *) mapView:(MKMapView *)theMapView viewForAnnotation:(id <MKAnnotation>) annotation { static NSString *placemarkIdentifier = @"my annotation identifier"; if ([annotation isKindOfClass:[MyAnnotation class]]) { MKAnnotationView *annotationView = [theMapView dequeueReusableAnnotationViewWithIdentifier:placemarkIdentifier]; if (annotationView == nil) { annotationView = [[MKAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:placemarkIdentifier]; annotationView.image = [UIImage imageNamed:@"blood_orange.png"]; } else annotationView.annotation = annotation; return annotationView; } return nil;}
10. 取得真真實位址
樣本:初始化MKReverseGeocoderMKReverseGeocoder *geocoder = [[MKReverseGeocoder alloc] initWithCoordinate:coordinates];geocoder.delegate = self;[geocoder start]; 如果無法處理座標,則調用reverseGeocoder:didFailWithError: 方法- (void)reverseGeocoder:(MKReverseGeocoder *)geocoder didFailWithError:(NSError *)error { NSLog(@"Error resolving coordinates: %@", [error localizedDescription]); geocoder.delegate = nil; [geocoder autorelease];} 如果成功,則調用reverseGeocoder:didFindPlacemark: 並把資訊儲存在MKPlacemark 中didFindPlacemark:(MKPlacemark *)placemark { NSString *streetAddress = placemark.thoroughfare; NSString *city = placemark.locality; NSString *state = placemark.administrativeArea; NSString *zip = placemark.postalCode; // Do something with information geocoder.delegate = nil; [geocoder autorelease];}