MKMapView和MKMapViewDelegate
- @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 method
- returns 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 View
- Annotation 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]];
- 移除一个Annotation
- removeAnnotation:
- 移除一个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. 取得真实地址
- 示例:
- 初始化MKReverseGeocoder
- MKReverseGeocoder *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];
- }