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];
}

你可能感兴趣的:(MKMapView和MKMapViewDelegate)