iOS 大头针怎么左右固定 中间自适应在中间,且移动后及时更新位置信息

下次自动登录
关注移动互联网和移动APP开发工具、开发框架、测试工具、微信开发、Android源码、Android开源类库以及各种开源组件的IT科技网站
现在的位置:
iOS开发——定位和位置信息方法总结
定位和获取位置信息是移动社交应用和LBS应用不可或缺的功能,因此本文重点介绍iOS开发中的定位和获取位置信息的方法,分享给iOS程序员兄弟们。
要实现地图、导航功能,往往需要先熟悉定位功能,在iOS中通过Core Location框架进行定位操作。Core Location自身可以单独使用,和地图开发框架MapKit完全是独立的,但是往往地图开发要配合定位框架使用。在Core Location中主要包含了定位、地理编码(包括反编码)功能。
定位是一个很常用的功能,如一些地图软件打开之后如果用户允许软件定位的话,那么打开软件后就会自动锁定到当前位置,如果用户手机移动那么当前位置也会跟随着变化。要实现这个功能需要使用Core Loaction中CLLocationManager类 。首先看一下这个类的一些主要方法和属性:
iOS 8 还提供了更加人性化的定位服务选项。App 的定位服务不再仅仅是关闭或打开,现在,定位服务的启用提供了三个选项,「永不」「使用应用程序期间」和「始终」。同时,考虑到能耗问题,如果一款 App 要求始终能在后台开启定位服务,iOS 8 不仅会在首次打开 App 时主动向你询问,还会在日常使用中弹窗提醒你该 App 一直在后台使用定位服务,并询问你是否继续允许。在iOS7及以前的版本,如果在应用程序中使用定位服务只要在程序中调用 startUpdatingLocation方法应用就会询问用户是否允许此应用是否允许使用定位服务,同时在提示过程中可以通过在info.plist 中配置通过配置Privacy - Location Usage Description告诉用户使用的目的,同时这个配置是可选的。
但是在iOS8中配置配置项发生了变化,可以通过配置NSLocationAlwaysUsageDescription或者 NSLocationWhenInUseUsageDescription来告诉用户使用定位服务的目的,并且注意这个配置是必须的,如果不进行配置则默 认情况下应用无法使用定位服务,打开应用不会给出打开定位服务的提示,除非安装后自己设置此应用的定位服务。同时,在应用程序中需要根据配置对 requestAlwaysAuthorization或locationServicesEnabled方法进行请求。由于本人机器已经更新到最新的 iOS8.1下面的内容主要针对iOS8,使用iOS7的朋友需要稍作调整。
下面我就总结了下定位功能的简单实现。
定位和反查位置信息要加载两个动态库 CoreLocation.framework 和 MapKit.framework 一个获取坐标一个提供反查
RootViewController的.h文件中,
RootViewController的.m文件中,
button的响应方法,当点击button的时候开始等位
locationManager的代理方法
本文到此结束,希望给在开发定位和获取位置信息遇到困难的iOS程序员兄弟们带来帮助。
【上篇】【下篇】iOS使用位置和方向服务
Core Location为定位用户当前位置和方向(Heading)提供支持,它负责从相应的设备硬件收集信息,并以异步的方式报告给您的应用程序。数据是否可用取决于设备的类型以及所需的硬件当前是否打开,如果设备处于飞行模式,则某些硬件可能不可用。
在使用Core Location框架的接口之前,必须将CoreLocation.framework加入到您的Xcode工程中,并在相关的目标中进行连接。要访问该框架的类和头文件,还需要在相应的源代码文件的顶部包含#import
语句。更多有关如何在工程中加入框架的信息,请参见文档中的部分。
有关Core Location框架的类的一般性信息请参见。
取得用户的当前位置
Location框架使您可以定位设备的当前位置,并将这个信息应用到程序中。该框架利用设备内置的硬件,在已有信号的基础上通过三角测量得到固定位置,然后将它报告给您的代码。在接收到新的或更为精确的信号时,该框架还对位置信息进行更新。
如果您确实需要使用Core
Location框架,则务必控制在最小程度,且正确地配置位置服务。收集位置数据需要给主板上的接收装置上电,并向基站、Wi-Fi热点、或者GPS卫星查询,这个过程可能要花几秒钟的时间。此外,请求更高精度的位置数据可能需要让接收装置更长时间地处于打开状态,而长时间地打开这个硬件会耗尽设备的电池。如果位置信息不是频繁变化,通常可以先取得初始位置,然后每隔一段时间请求一次更新就可以了。如果您确实需要定期更新位置信息,也可以为位置服务设置一个最小的距离阈值,从而最小化代码必须处理的位置更新。
取得用户当前位置首先要类的实例,并用期望的精度和阈值参数进行配置。开始接收通告则需要为该对象分配一个,然后调用方法来确定用户当前位置。当新的位置数据到来时,位置管理器会通知它的委托对象。如果位置更新通告已经发送完成,您也可以直接从CLLocationManager对象获取最新的位置数据,而不需要等待新的事件。
程序清单8-7展示了定制的startUpdates方法和委托方法的的一个实现。startUpdates方法创建一个新的位置管理器对象(如果尚未存在的话),并用它启动位置更新事件的递送(在这个实例中,locationManager变量是MyLocationGetter类中声明的成员变量,该类遵循。事件处理方法通过事件的时间戳来确定其延迟的程度,对于太过时的事件,该方法会直接忽略,并等待更为实时的事件。在得到足够实时的数据后,即关闭位置服务。
程序清单8-7&&发起和处理位置更新事件
@implementation MyLocationGetter
- (void)startUpdates
// Create the location manager if this object does not
// already have one.
if (nil == locationManager)
locationManager = [[CLLocationManager alloc] init];
locationManager.delegate =
locationManager.desiredAccuracy = kCLLocationAccuracyKilom
// Set a movement threshold for new events
locationManager.distanceFilter = 500;
[locationManager startUpdatingLocation];
// Delegate method from the CLLocationManagerDelegate protocol.
- (void)locationManager:(CLLocationManager *)manager
didUpdateToLocation:(CLLocation *)newLocation
fromLocation:(CLLocation *)oldLocation
// If it's a relatively recent event, turn off updates to save power
NSDate* eventDate = newLocation.
NSTimeInterval howRecent = [eventDate timeIntervalSinceNow];
if (abs(howRecent) & 5.0)
[manager stopUpdatingLocation];
printf("latitude %+.6f, longitude %+.6f\n",
newLocation.coordinate.latitude,
newLocation.coordinate.longitude);
// else skip the event and process the next one.
对时间戳进行检查是推荐的做法,因为位置服务通常会立即返回最后缓存的位置事件。得到一个大致的固定位置可能要花几秒钟的时间,更新之前的数据只是反映最后一次得到的数据。您也可以通过精度来确定是否希望接收位置事件。位置服务在收到精度更高的数据时,可能返回额外的事件,事件中的精度值也会反映相应的精度变化。
请注意:Core
Location框架在位置请求的一开始(而不是请求返回的时候)记录时间戳。由于Core
Location使用几个不同的技术来取得固定位置,位置请求返回的顺序有时可能和时间戳指示的顺序不同。这样,新事件的时间戳有时会比之前的事件还要老一点,这是正常的。Core
Location框架致力于提高每个新事件的位置精度,而不考虑时间戳的值。
获取与方向有关的事件
Location框架支持两种获取方向信息的方法。包含GPS硬件的设备可以提供当前移动方向的大致信息,该信息和经纬度数据通过同一个位置事件进行传递。包含磁力计的设备可以通过方向对象提供更为精确的方向信息,方向对象是类的实例。
通过GPS硬件取得大致方向的过程和部分的描述是一样的,框架会向您的应用程序传递一个对象,对象中的和包含相关的信息。这个接口适用于需要跟踪用户移动的大多数应用程序,比如实现汽车导航系统的导航程序。对于基于指南针或者可能需要了解用户静止时朝向的应用程序,可以请求位置管理器提供方向对象。
您的程序必须运行在包含磁力计的设备上才能接收方向对象。磁力计可以测量地球散发的磁场,进而确定设备的准确方向。虽然磁力计可能受到局部磁场(比如扬声器的永磁铁、马达、以及其它类型电子设备发出的磁场)的影响,但是Core
Location框架具有足够的智能,可以过滤很多局部磁场的影响,确保方向对象包含有用的数据。
请注意:如果路线或方向信息对于您的应用程序的必须的,则应该在程序的Info.plist文件中正确地包含UIRequiredDeviceCapabilities键。这个键用于指定应用程序正常工作需要具备的设备特性,您可以用它来指定设备必须具有GPS和磁力计硬件。更多有关这个键值设置的信息请参见部分。
为了接收方向事件,您需要创建一个对象,为其分配一个委托对象,并调用其方法,如程序清单8-8所示。然而,在请求方向事件之前,应该检查一下位置管理器的属性,确保相应的硬件是存在的。如果该硬件不存在,应用程序应该回退到通过位置事件获取路线信息的代码路径。
程序清单8-8&&发起方向事件的传送
CLLocationManager* locManager = [[CLLocationManager alloc] init];
if (locManager.headingAvailable)
locManager.delegate = myDelegateO // Assign your custom delegate object
locManager.headingFilter = 5;
[locManager startUpdatingHeading];
// Use location events instead
您赋值给delegate属性的对象必须遵循。当一个新的方向事件到来时,位置管理器会调用方法,将事件传递给您的应用程序。一旦收到新的事件,应用程序应该检查属性,确保刚收到的数据是有效的,具体做法如清单8-9。
程序清单8-9&&处理方向事件
- (void)locationManager:(CLLocationManager*)manager didUpdateHeading:(CLHeading*)newHeading
// If the accuracy is valid, go ahead and process the event.
if (newHeading.headingAccuracy & 0)
CLLocationDirection theHeading = newHeading.magneticH
// Do something with the event data.
CLHeading对象的属性包含主方向数据,且该数据一直存在。这个属性给出了相对于磁北极的方向数据,磁北极和北极不在同一个位置上。如果您希望得到相对于北极(也称为地理北极)的方向数据,则必须在startUpdatingHeading之前调用startUpdatingLocation方法来启动位置更新,然通过CLHeading对象的属性取得相对于地理北极的方向。
显示地图和注解
iPhone OS 3.0引入了Map Kit。通过这个框架可以在应用程序的窗口中嵌入一个全功能的地图界面。Maps程序中的很多常见功能都包含在这个框架提供的地图支持中,您可以通过它来显示标准的街道地图、卫星图像,或两者的组合;还可以通过代码来缩放和移动地图。该框架还自动支持触摸事件,用户可以用手指缩放或移动地图。您还可以在地图中加入自己定制的注释信息,以及用框架提供的反向地理编码功能寻找和地图坐标关联的地址。
在使用Map Kit框架的功能之前,必须将MapKit.framework加入到Xcode工程中,并且在相关的目标中加以连接;在访问框架的类和头文件之前,需要在相应的源代码文件的顶部加入#import
语句。有关如何将框架加入工程的更多信息,请参见中的部分;有关Map
Kit框架类的一般性信息,则请参见。
重要提示:Map
Kit框架使用Google的服务来提供地图数据。框架及其相关接口的使用必须遵守Google Maps/Google Earth
API的服务条款,具体条款信息位于。
在用户界面中加入地图视图
为应用程序加入地图之前,需要在应用程序的视图层次中嵌入一个类的实例,该类为地图信息的显示和用户交互提供支持。您可以通过代码来为该类,并通过方法来对其进行,或者用Interface
Builder将它加入到中。
地图视图也是个视图,因此您可以通过它的随意调整它的位置和尺寸。虽然地图视图本身没有提供任何控件,但是您可以在它的上面放置工具条或其它视图,使用户可以和地图内容进行交互。您在地图视图中加入的所有子视图的位置是不变的,不会随着地图内容的滚动而滚动。如果您希望在地图上加入定制的内容,并使它们跟着地图滚动,则必须创建注解,具体描述请参见部分。
MKMapView类有很多属性,可以在显示之前进行配置,其中最重要的是属性,负责定义最初显示的地图部分及如何缩放和移动地图内容。
缩放和移动地图内容
MKMapView类的属性控制着当前显示的地图部分。当您希望缩放和移动地图时,需要做的只是正确改变这个属性的值。这个属性包含一个类型的结构,其定义如下:
typedef struct {
CLLocationCoordinate2D
MKCoordinateS
} MKCoordinateR
改变center域可以将地图移动到新的位置;而改变span域的值则可以实现缩放。这些域的值需要用地图坐标来指定,地图坐标用度、分、和秒来度量。对于span域,您需要通过经纬度距离来指定它的值。虽然纬度距离相对固定,每度大约111公里,但是经度距离却是随着纬度的变化而变化的。在赤道上,经度距离大约每度111公里;而在地球的极点上,这个值则接近于零。当然,您总是可以通过函数来创建基于公里值(而不是度数)的区域。
如果您希望在更新地图时不显示过程动画,可以直接修改region或centerCoordinate属性的值;如果需要动画过程,则必须使用或方法。方法可以移动地图,且避免在无意中触发缩放,而setRegion:animated:方法则可以同时缩放和移动地图。举例来说,如果您要使地图向左移动,移动距离为当前宽度的一半,则可以通过下面的代码找到地图左边界的坐标,然后将它用于中心点的设置,如下所示:
CLLocationCoordinate2D mapCenter = myMapView.centerC
mapCenter = [myMapView convertPoint:
CGPointMake(1, (myMapView.frame.size.height/2.0))
toCoordinateFromView:myMapView];
[myMapView setCenterCoordinate:mapCenter animated:YES];
缩放地图则应该修改span属性的值,而不是中心坐标。减少span属性值可以使视图缩小;相反,增加该属性值可以使视图放大。换句话说,如果当前的span值是一度,将它指定为两度会使地图跨度放大两倍:
MKCoordinateRegion theRegion = myMapView.
// Zoom out
theRegion.span.longitudeDelta *= 2.0;
theRegion.span.latitudeDelta *= 2.0;
[myMapView setRegion:theRegion animated:YES];
显示用户的当前位置
Map Kit框架内置支持将用户的当前位置显示在地图上,具体做法是将地图视图对象的属性值设置为YES就可以了。进行这个设置会使地图视图通过Core
Location框架找到用户位置,并在地图上加入类型为的注解。
在地图上加入MKUserLocation注解对象的事件会通过对象进行报告,这和定制注解的报告方式是一样的。如果您希望在用户位置上关联一个定制的注解视图,应该在委托对象的方法中返回该视图。如果您希望使用缺省的注解视图,则应该在该方法中返回nil。
坐标和像素之间的转换
您通常通过经纬度值来指定地图上的点,但有些时候也需要在经纬度值和地图视图对象中的像素之间进行转换。举例来说,如果您允许用户在地图表面拖动注解,定制注解视图的事件处理器代码就需要将边框坐标转换为地图坐标,以便更新关联的注解对象。类中几个例程,用于在地图坐标和地图视图对象的本地坐标系统之间进行转换,这些例包括:
有关如何处理定制注解事件的更多信息,请参见部分。
注解是您定义并放置在地图上面的信息片段。Map Kit将注解实现为两个部分,即注解对象和用于显示注解的视图。大多数情况下,您需要负责提供这些定制对象,但框架也提供一些标准的注解和视图供您使用。
在地图视图上显示注解需要两个步骤:
注解对象是指遵循的任何对象。通常情况下,注解对象是相对小的数据对象,存储注解的坐标及相关信息,比如注解的名称。注解是通过协议来定义的,因此应用程序中的任何对象都可以成为注解对象。然而,在实践上,注解对象应该是轻量级的,因为在显式删除注解对象之前,地图视图会一直保存它们的引用。注意,同样的结论并不一定适用于注解视图。
在将注解显示在屏幕上时,地图视图负责确保注解对象具有相关联的注解视图,具体的方法是在注解坐标即将变为可见时调用其委托对象的mapView:viewForAnnotation:方法。但是,由于注解视图的量级通常总是比其对应的注解对象更重,所以地图对象尽可能不在内存中同时保存很多注解视图。为此,它实现了注解视图的回收机制。这个机制和表视图在滚动时回收表单元使用的机制相类似,即当一个注解视图移出屏幕时,地图视图就解除其与注解对象之间关联,将它放入重用队列。而在创建新的注解视图之前,委托的mapView:viewForAnnotation:方法应该总是调用地图对象的方法来检查重用队列中是否还有可用的视图对象。如果该方法返回一个正当的视图对象,您就可以对其进行再次初始化,并将它返回;否则,您再创建和返回一个新的视图对象。
添加和移除注解对象
您不应直接在地图上添加注解视图,而是应该添加注解对象,注解对象通常不是视图。注解对象可以是应用程序中遵循协议的任何对象。注解对象中最重要的部分是它的,它是MKAnnotation协议必需实现的属性,用于为地图上的注解提供锚点。
往地图视图加入注解所需要的全部工作就是调用地图视图对象的或方法。何时往地图视图加入注解以及何时为加入的注解提供用户界面由您自己来决定。您可以提供一个工具条,由用户通过工具条上的命令来创建注解,或者也可以自行编码创建注解,注解信息可能来自本地或远程的数据库信息。
如果您的应用程序需要删除某个老的注解,则在删除之前,应该调用或方法将它从地图中移除。地图视图会显示它知道的所有注解,如果您不希望某些注解被显示在地图上,就需要显式地将它们删除。例如,如果您的应用程序允许用户对餐厅或本地风景点进行过滤,就需要删除与过滤条件不相匹配的所有注解。
定义注解视图
Map Kit框架提供了两个注解视图类:MKAnnotationView和MKPinAnnotationView。类是一个具体的视图,定义了所有注解视图的基本行为。类则是MKAnnotationView的子类,用于在关联的注解坐标点上显示一个标准的系统大头针图像。
您可以将MKAnnotationView类用于显示简单的注解,也可以从该类派生出子类,提供更多的交互行为。在直接使用该类时,您需要提供一个定制的图像,用于在地图上表示您希望显示的内容,并将它赋值给注解视图的属性。如果您显示的内容不需要动态改变,而且不需要支持用户交互,则这种用法是非常合适的。但是,如果您需要支持动态内容和用户交互,则必须定义定制子类。
在一个定制的子类中,有两种方式可以描画动态内容:可以继续使用image属性来显示注解图像,这样或许需要设置一个定时器,负责定时改变当前的图像;也可以重载视图的方法来显示描画您的内容,这种方法也需要设置一个定时器,以定时调用视图的方法。
如果您通过drawRect:方法来描画内容,则必须记住:要在注解视图初始化后不久为其指定尺寸。注解视图的缺省方法并不包含边框矩形参数,而是在初始化后通过您分配给image属性的图像来设置边框尺寸。如果您没有设置图像,就必须显式设置边框尺寸,您渲染的内容才会被显示。
有关如何在注解视图中支持用户交互的信息,请参见部分;有关如何设置定时器的信息,则请参见。
创建注解视图
您应该总是在的创建注解视图。在创建新视图之前,您应该总是调用方法来检查是否有可重用的视图,如果该方法返回非nil值,就应该将地图视图提供的注解分配给重用视图的属性,并执行其它必要的配置,使视图处于期望的状态,然后将它返回;如果该方法返回nil,则应该创建并返回一个新的注解视图对象。
程序清单8-10是mapView:viewForAnnotation:方法的一个例子实现,展示了如何为定制注解对象提供大头针注解视图。如果队列中已经存在一个大头针注解视图,该方法就将它和相应的注解对象相关联;如果重用队列中没有视图,该方法则创建一个新的视图,对其基本属性进行配置,并为插图符号配置一个附加视图。
程序清单8-10&&创建注解视图
- (MKAnnotationView *)mapView:(MKMapView *)mapView
viewForAnnotation:(id )annotation
// If it's the user location, just return nil.
if ([annotation isKindOfClass:[MKUserLocation class]])
// Handle any custom annotations.
if ([annotation isKindOfClass:[CustomPinAnnotation class]])
// Try to dequeue an existing pin view first.
MKPinAnnotationView*
pinView = (MKPinAnnotationView*)[mapView
dequeueReusableAnnotationViewWithIdentifier:@"CustomPinAnnotation"];
if (!pinView)
// If an existing pin view was not available, create one
pinView = [[[MKPinAnnotationView alloc] initWithAnnotation:annotation
reuseIdentifier:@"CustomPinAnnotation"]
autorelease];
pinView.pinColor = MKPinAnnotationColorR
pinView.animatesDrop = YES;
pinView.canShowCallout = YES;
// Add a detail disclosure button to the callout.
UIButton* rightButton = [UIButton buttonWithType:
UIButtonTypeDetailDisclosure];
[rightButton addTarget:self action:@selector(myShowDetailsMethod:)
forControlEvents:UIControlEventTouchUpInside];
pinView.rightCalloutAccessoryView = rightB
pinView.annotation =
return pinV
处理注解视图中的事件
虽然注解视图位于地图内容上面的特殊层中,但它们也是功能完全的视图,能够接收触摸事件。您可以通过这些事件来实现用户和注解之间的交互。比如,您可以通过视图中的触摸事件来实现注解在地图表面的拖拽行为。
请注意:由于地图被显示在一个滚动界面上,所以,在用户触击定制视图和事件最终被派发之间往往有一个小的延迟。滚动视图可以利用这个延迟来确定触摸事件是否为某种滚动手势的一部分。
随后的一系列示例代码将向您展示如何实现一个支持用户拖动的注解视图。例子中的注解视图直接在注解坐标点上显示一个公牛眼图像,并包含一个定制的附加视图,用以显示目的地的详细信息。图8-1显示注解视图的一个实例以及其包含的气泡符号。
图8-1&&公牛眼注解视图
程序清单8-11显示了BullseyeAnnotationView类的定义。类中包含一些正确跟踪视图移动需要的其它成员变量,以及一个指向地图视图本身的指针,指针的值是在mapView:viewForAnnotation:方法中设置的,该方法是创建或再次初始化注解视图的地方。在事件跟踪完成后,代码需要调整注解对象的地图坐标,这时需要用到地图视图对象。
程序清单8-11&&BullseyeAnnotationView类
@interface BullseyeAnnotationView : MKAnnotationView
CGPoint startL
CGPoint originalC
MKMapView*
@property (assign,nonatomic) MKMapView*
- (id)initWithAnnotation:(id )
@implementation BullseyeAnnotationView
- (id)initWithAnnotation:(id )annotation
self = [super initWithAnnotation:annotation
reuseIdentifier:@"BullseyeAnnotation"];
theImage = [UIImage imageNamed:@"bullseye32.png"];
if (!theImage)
self.image = theI
self.canShowCallout = YES;
self.multipleTouchEnabled = NO;
rightButton = [UIButton buttonWithType:
UIButtonTypeDetailDisclosure];
[rightButton addTarget:self action:@selector(myShowAnnotationAddress:)
forControlEvents:UIControlEventTouchUpInside];
self.rightCalloutAccessoryView = rightB
当触击事件首次到达公牛眼视图时,该类的方法会记录事件的信息,作为初始信息,如清单8-12所示。方法会利用这些信息来调整视图位置。所有的位置信息都存储在父视图的坐标空间中。
程序清单8-12&&跟踪视图的位置
@implementation BullseyeAnnotationView (TouchBeginMethods)
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
// The view is configured for single touches only.
UITouch* aTouch = [touches anyObject];
startLocation = [aTouch locationInView:[self superview]];
originalCenter = self.
[super touchesBegan:touches withEvent:event];
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
UITouch* aTouch = [touches anyObject];
CGPoint newLocation = [aTouch locationInView:[self superview]];
CGPoint newC
// If the user's finger moved more than 5 pixels, begin the drag.
if ( (abs(newLocation.x - startLocation.x) & 5.0) ||
(abs(newLocation.y - startLocation.y) & 5.0) )
isMoving = YES;
// If dragging has begun, adjust the position of the view.
if (isMoving)
newCenter.x = originalCenter.x + (newLocation.x - startLocation.x);
newCenter.y = originalCenter.y + (newLocation.y - startLocation.y);
self.center = newC
// Let the parent class handle it.
[super touchesMoved:touches withEvent:event];
当用户停止拖动注解视图时,您需要调整原有注解的坐标,确保视图位于新的位置。清单8-13显示了BullseyeAnnotationView类的方法,该方法通过地图成员变量将基于像素的点转化为地图坐标值。由于注解的属性通常是只读的,所以例子中的注解对象实现了一个名为changeCoordinate的定制方法,负责更新它在本地存储的值,而这个值可以通过coordinate属性取得。如果触摸事件由于某种原因被取消,方法会使注解视图回到原来的位置。
程序清单8-13&&处理最后的触摸事件
@implementation BullseyeAnnotationView (TouchEndMethods)
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
if (isMoving)
// Update the map coordinate to reflect the new position.
CGPoint newCenter = self.
BullseyeAnnotation* theAnnotation = self.
CLLocationCoordinate2D newCoordinate = [map convertPoint:newCenter
toCoordinateFromView:self.superview];
[theAnnotation changeCoordinate:newCoordinate];
// Clean up the state information.
startLocation = CGPointZ
originalCenter = CGPointZ
isMoving = NO;
[super touchesEnded:touches withEvent:event];
- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event
if (isMoving)
// Move the view back to its starting point.
self.center = originalC
// Clean up the state information.
startLocation = CGPointZ
originalCenter = CGPointZ
isMoving = NO;
[super touchesCancelled:touches withEvent:event];
通过反向地理编码器获取地标信息
Kit框架主要处理地图坐标值。地图坐标值由经度和纬度组成的,比较易于在代码中使用,但却不是用户最容易理解的描述方式。为使用户更加易于理解,您可以通过类来取得与地图坐标相关联的地标信息,比如街道地址、城市、州、和国家。
MKReverseGeocoder类负责向潜在的地图服务查询指定地图坐标的信息。由于需要访问网络,反向地理编码器对象总是以异步的方式执行查询,并将结果返回给相关联的。委托对象必须遵循协议。
启动反向地理编码器的具体做法是首先创建一个MKReverseGeocoder类的实例,并将恰当的对象赋值给该实例的属性,然后调用方法。如果查询成功完成,您的委托就会收到带有一个对象的查询结果。MKPlacemark对象本身也是注解对象—也就是说,它们采纳了—因此如果您愿意的话,可以将它们添加到地图视图的注解列表中。
已投稿到:
以上网友发言只代表其个人观点,不代表新浪网的观点或立场。}

我要回帖

更多关于 固定资产转固不及时 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信