zoukankan      html  css  js  c++  java
  • (八十)MapKit放置系统默认大头针和自定义大头针

    有关MapView的显示和定位在上一节已经说明,这一节说明如何在地图上放置大头针,以及设置点击大头针的视图。

    【系统默认大头针】

    mapView上放置大头针的方法是调用其addAnnotation:方法,需要注意的是,传入的是模型而不是大头针视图。

    - (void)addAnnotation:(id <MKAnnotation>)annotation;
    通过这个方法,我们可以清楚的看到,annotation模型需要遵循MKAnnotation协议,我们打开这个协议,可以看到如下的内容:

    @protocol MKAnnotation <NSObject>
    
    // Center latitude and longitude of the annotation view.
    // The implementation of this property must be KVO compliant.
    @property (nonatomic, readonly) CLLocationCoordinate2D coordinate;
    
    @optional
    
    // Title and subtitle for use by selection UI.
    @property (nonatomic, readonly, copy) NSString *title;
    @property (nonatomic, readonly, copy) NSString *subtitle;
    
    // Called as a result of dragging an annotation view.
    - (void)setCoordinate:(CLLocationCoordinate2D)newCoordinate NS_AVAILABLE(10_9, 4_0);
    
    @end
    因此我们应当定义一个模型,按照协议定义这些属性,其中coordinate是必须定义的,因为大头针必须有位置。

    模型类遵循MKAnnocation协议,命名为MyAnnotation,如下:

    #import <Foundation/Foundation.h>
    #import <MapKit/MapKit.h>
    
    @interface MyAnnotation : NSObject<MKAnnotation>
     /**
     *  大头针的位置
     */
    @property (nonatomic, assign) CLLocationCoordinate2D coordinate;
    /**
     *  大头针标题
     */
    @property (nonatomic, copy) NSString *title;
    /**
     *  大头针的子标题
     */
    @property (nonatomic, copy) NSString *subtitle;
    @end
    #import "MyAnnotation.h"
    
    @implementation MyAnnotation
    
    @end


    然后就可以通过定义模型,调用addAnnotation:方法添加一枚大头针,例如我们通过Button,随机添加一枚大头针:

    - (IBAction)addPin:(id)sender {
        
        MyAnnotation *anno = [[MyAnnotation alloc] init];
        anno.title = @"title";
        anno.subtitle = @"subtitle";
        CLLocationDegrees latitude = 36.821119 + arc4random_uniform(20);
        CLLocationDegrees longtitude = 116.750112 + arc4random_uniform(20);
        anno.coordinate = CLLocationCoordinate2DMake(latitude, longtitude);
        
        [self.mapView addAnnotation:anno];
    }

    其中的title和subtitle是点击大头针时显示的气泡上的标题和副标题。

    大头针的显示原理和tableView显示cell是类似的,一旦调用addAnnotation:方法,就会调用mapView:viewForAnnotationView:方法,这个方法中应当从缓存池取出一个大头针视图,或者如果缓存池中没有新建一个大头针视图,然后返回。

    与tableView的区别是,如果直接返回nil,则会按照系统的样式返回大头针。

    需要注意的是,如果不返回nil,要对不同类型的大头针进行处理,不要忘了用户的位置指示圆点也属于一种大头针,如果只是单单的设置大头针,连用户位置也会是一颗针而不是圆点


    判断方法很简单,因为用户位置大头针由系统创建,因此传入的模型肯定不是我们自己的模型MyAnnotation,只要判断传入的模型是不是这个类,如果不是,则返回nil,代表按照系统默认样式,创建圆点。


    要创建大头针,使用的是MKPinAnnotationView,如果使用MKAnnotationView,是不带图片的,无法直接显示。

    - (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id<MKAnnotation>)annotation{
        
        static NSString *ID = @"anno";
        // 如果返回nil,系统会按照默认方式显示,如果自定义,是无法直接显示的,并且点击大头针之后不会显示标题,需要自己手动设置显示
        // 如果想要直接显示,应该调用MKPinAnnotationView
        MKPinAnnotationView *annoView = (MKPinAnnotationView *)[mapView dequeueReusableAnnotationViewWithIdentifier:ID];
        
        if (annoView == nil) {
            annoView = [[MKPinAnnotationView alloc] initWithAnnotation:nil reuseIdentifier:ID];
            // 大头针属性
            annoView.animatesDrop = YES; // 设置大头针坠落的动画
            annoView.canShowCallout = YES; // 设置点击大头针是否显示气泡
            annoView.calloutOffset = CGPointMake(0, 0); // 设置大头针气泡的偏移
            // 设置大头针气泡的左右视图、可以为任意UIView
            annoView.leftCalloutAccessoryView = [UIButton buttonWithType:UIButtonTypeContactAdd];
            annoView.rightCalloutAccessoryView = [[UISwitch alloc] init];
            [annoView setPinColor:MKPinAnnotationColorPurple]; // 设置大头针颜色
        }
        
        // 设置大头针的图片,如果是直接创建MKPin,则无效。
        //annoView.image = [UIImage imageNamed:@"pin"];
        
        annoView.annotation = annotation;
        
        // 如果是用户位置,应当显示默认的圆点而不是大头针,因此应当判断是否是MyAnnotation
        if(![annoView.annotation isKindOfClass:[MyAnnotation class]]){
            return nil;
        }
        
        return annoView;
        
    }

    【自定义大头针】

    自定义大头针需要使用MKAnnotationView,自己指定image,没有坠落动画,其他没有区别。

     (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id<MKAnnotation>)annotation{
        
        static NSString *ID = @"anno";
        // 如果返回nil,系统会按照默认方式显示,如果自定义,是无法直接显示的,并且点击大头针之后不会显示标题,需要自己手动设置显示
        // 如果想要直接显示,应该调用MKPinAnnotationView
        MKAnnotationView *annoView = [mapView dequeueReusableAnnotationViewWithIdentifier:ID];
        
        if (annoView == nil) {
            annoView = [[MKPinAnnotationView alloc] initWithAnnotation:nil reuseIdentifier:ID];
            // 大头针属性
            //annoView.animatesDrop = YES; // MKPinAnnotaionView才有效,设置大头针坠落的动画
            annoView.canShowCallout = YES; // 设置点击大头针是否显示气泡
            annoView.calloutOffset = CGPointMake(0, 0); // 设置大头针气泡的偏移
            // 设置大头针气泡的左右视图、可以为任意UIView
            annoView.leftCalloutAccessoryView = [UIButton buttonWithType:UIButtonTypeContactAdd];
            annoView.rightCalloutAccessoryView = [[UISwitch alloc] init];
            //[annoView setPinColor:MKPinAnnotationColorPurple]; // MKPinAnnotaionView才有效,设置大头针的颜色
        }
        
        // 设置大头针的图片
        annoView.image = [UIImage imageNamed:@"pin"];
        
        annoView.annotation = annotation;
        
        // 如果是用户位置,应当显示默认的圆点而不是大头针,因此应当判断是否是MyAnnotation
        if(![annoView.annotation isKindOfClass:[MyAnnotation class]]){
            return nil;
        }
        
        return annoView;
        
    }

    【MVC封装annotationView的注意点】

    annotation要传入模型,在重写的set方法里,注意调用父类的set方法,先设置公共属性,再设置自己所特有的。

    有一个细节,默认set方法的传入模型是id<MKAnnotaion>类型,在使用时还需要强转类型,为了方便,我们直接把类型改为MyAnnotation,因为OC在调用方法时发送的消息只包括方法名和冒号、描述,因此类型不属于方法名的一部分,可以修改。

    - (void)setAnnotation:(MyAnnotation *)annotation{
       [super setAnnotation:annotation];
       // 设置特有的属性,例如图片、左右视图等。
    }


  • 相关阅读:
    2019年CSP-J初赛试题(普及组)试题详解
    开放课件
    猴子选大王 (约瑟夫问题)
    后缀表达式转中缀表达式
    JDBC的使用
    JDBC
    MySQL第五天
    MySQL第四天
    MySQL第三天
    MySQL第二天
  • 原文地址:https://www.cnblogs.com/aiwz/p/6154121.html
Copyright © 2011-2022 走看看