(八十)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];
   // 设置特有的属性,例如图片、左右视图等。
}

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-10-25 02:29:04

(八十)MapKit放置系统默认大头针和自定义大头针的相关文章

MapKit之大头针全面解析(使用系统大头针、自定义大头针callout视图、使用图片显示大头针)

首先了解一些相关知识点: 添加大头针到地图 在iOS开发中经常会标记某个位置,需要使用地图标注,也就是大家俗称的"大头针".大头针(Annotations)提供了一种方式来突出地图中具体的位置并可以提供相关的信息.我们能够使用大头针标记具体的地址,兴趣点和其他类型的目的地.当显示在地图上的时候,大头针可以使用图片作为标识,也能够点击大头针弹出小弹框提供相应的链接和具体内容.Figure6-1显示了系统标准的大头针样式标记具体的位置,并提供了小弹框显示额外的信息,使用箭头提示用户点击获取

第三百八十三节,Django+Xadmin打造上线标准的在线教育平台—路由映射与静态文件配置

第三百八十四节,Django+Xadmin打造上线标准的在线教育平台-路由映射与静态文件配置以及会员注册 基于类的路由映射 from django.conf.urls import url, include # 导入django自在的include逻辑 from django.contrib import admin from django.views.generic import TemplateView # 导入django自带的TemplateView逻辑 import xadmin #

第三百八十九节,Django+Xadmin打造上线标准的在线教育平台—列表筛选结合分页

第三百八十九节,Django+Xadmin打造上线标准的在线教育平台-列表筛选结合分页 根据用户的筛选条件来结合分页 实现原理就是,当用户点击一个筛选条件时,通过get请求方式传参将筛选的id或者值,传入逻辑处理就行数据库条件查询,将查询条件值在返回html页面判断是否是选中样式,最后将所有需要关联的筛选请求加上彼此逻辑处理传回来的查询条件值 html请求传参 黄色背景为请求传参 红色背景为逻辑处理传过来的查询条件判断样式 <div class="wp butler_list_box li

第三百八十五节,Django+Xadmin打造上线标准的在线教育平台—登录功能实现,回填数据以及错误提示html

第三百八十五节,Django+Xadmin打造上线标准的在线教育平台-登录功能实现 1,配置登录路由 from django.conf.urls import url, include # 导入django自在的include逻辑 from django.contrib import admin from django.views.generic import TemplateView # 导入django自带的TemplateView逻辑 import xadmin # 导入xadmin fr

第十五单元 &nbsp; 系统虚拟机管理

第十五单元 系统虚拟机管理 一 安装 #!/bin/bash:命令运行环境的指定 virt-install \:安装虚拟机 --name $1 \:虚拟机名称指定,$1表示脚本后的第一串字符 --ram 1000 \:内存 --file /var/lib/libvirt/images/$1.img \:硬盘文件 --file-size 8 \ :硬盘文件大小 --cdrom /var/ftp/pub/iso/rhel-server-7.1-x86_64-dvd.iso &  :安装源指定,&

孤荷凌寒自学python第八十天开始写Python的第一个爬虫10

(完整学习过程屏幕记录视频地址在文末) 原计划今天应当可以解决读取所有页的目录并转而取出所有新闻的功能,不过由于学习时间不够,只是进一步优化了自定义函数的写法. 一.优化并新增了几个操作word文档的函数 ``` #!/usr/bin/env python3 # -*- coding: utf-8 -*- import string import time import random from docx.enum.style import WD_STYLE_TYPE #所有样式 (包括段落.文字

修改ubuntu系统默认语言

中文乱码 安装ubuntu系统的时候为了方便选择了中文,出现了问题. (1)在终端中中文会显示乱码,因此需要将默认语言改为英文. (2)报错中文显示,不好查找原因和解决办法 修改默认系统默认语言 (1)用vi(或nano等文本编辑器)打开 /etc/default/locale 文件 将原来的配置内容注释掉添加 LANG="en_US.UTF-8″ LANGUAGE="en_US:en" (2)如下操作 $ sudo vi /etc/default/locale (3)再在终

Linux中的系统默认日志

/var/log/cron 记录了系统定时任务相关的日志 /var/log/cups 记录了打印信息的日志 /var/log/dmesg 记录了系统在开机时内核自检的信息,可以通过dmesg命令直接查看 /var/log/btmp 记录错误登录的日志,不能直接查看,是二进制文件,使用lastb命令查看 /var/log/lastlog 记录系统中所有用户最后一次登录时间,不能直接查看,是二进制文件,使用lastlog命令查看 /var/log/mailog 记录邮件信息 /var/log/mes

如何在TFS中恢复系统默认查询&rdquo;已指派给我&rdquo;的设置(TFS 2013)

故事是这样开始的,一天开发人员求助说,在浏览器中修改了系统默认的工作项查询"已指派给我"的后,发现这个查询每次都提示超时,并且没有办法恢复到初始的设置状态,因为出现超时提示以后,查询编辑器就无法使用,如下图: 找遍了所有可以编辑工作项查询的工具,Visual Studio, Eclipse都没有看到可以编辑系统默认查询的功能.即使在浏览器中使用"另存为"的方法把"已指派给我"保存为另外一个查询,也无法恢复系统默认的状态.已经觉得自己黔驴技穷了,并