iPhone开发:地图框架入门(一)
来源:互联网 发布:宝鸡时代网络 编辑:程序博客网 时间:2024/05/17 22:41
原文地址:http://www.highoncoding.com/Articles/804_Introduction_to_MapKit_Framework_for_iPhone_Development.aspx
地图对我们的生活来说是非常重要的一部分。我们经常用地图来确定位置和方向。这篇文章主要是用来介绍地图框架在ios里面的应用。
关键的概念:
MKMapView:用来在ios设备上显示地图的 UI 控件。
Annotation:用来在地图上展示的点,包括了很多的信息,比如坐标,标题,副标题等。
AnnotationView:定义点的视图部分,由 MKAnnotationView 这个类来定义。
1.参考的框架:
在下面的内容里面,我们将用到MapKit.framework 和 CoreLocation.framework 这个两个框架。在开始项目之前,把这两个框架添加到我们的项目里面。如图所示:
2.通过MKMapView这个UI来展示地图:
在添加这两个框架以后,我们准备开始创建我们的地图套件的应用。
第一步,在XB里面创建项目,拖动MKMapView这个UI。
The MapKitDemoAppDelegate.h 实现如下:
01
#import <UIKit/UIKit.h>
02
#import <MapKit/MapKit.h>
03
#import <CoreLocation/CoreLocation.h>
04
#import "MapPoint.h"
05
#import "LameAnnotationView.h"
06
07
@
interface
MapKitDemoAppDelegate : NSObject <UIApplicationDelegate,CLLocationManagerDelegate,MKMapViewDelegate,UITextFieldDelegate> {
08
09
CLLocationManager *locationManager;
10
IBOutlet MKMapView *mapView;
11
12
}
13
14
@property (nonatomic, retain) IBOutlet UIWindow *window;
15
@property (nonatomic,retain) IBOutlet MKMapView *mapView;
16
17
@end
di er bu
第二步:确定当前的位置:
在 MapKitDemoAppDelegate.m里面添加下面的代码:
01
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
02
{
03
self.mapView.
delegate
= self;
04
05
locationManager = [[CLLocationManager alloc] init];
06
[locationManager setDelegate:self];
07
08
[locationManager setDistanceFilter:kCLDistanceFilterNone];
09
[locationManager setDesiredAccuracy:kCLLocationAccuracyBest];
10
11
[self.mapView setShowsUserLocation:YES];
12
13
14
// Override point for customization after application launch.
15
[self.window makeKeyAndVisible];
16
return
YES;
17
}
CLLocationManage是用来获得用户当前位置的类,下面这行代码使得mapview获得用户当前的位置:
1
[self.mapView setShowsUserLocation:YES];
点击Run,我们可以在仿真器上看到这样的结果:
现在我们能看到用户在地图上被定位,但是现在只是看见了这一个点,我们需要放大这个区域,获得更加具体的信息。通过下面的代码,能够实现这个功能。
在 MapKitDemoAppDelegate.m里面添加下面的代码:
1
- (
void
)mapView:(MKMapView *)mv didAddAnnotationViews:(NSArray *)views
2
{
3
MKAnnotationView *annotationView = [views objectAtIndex:0];
4
id<MKAnnotation> mp = [annotationView annotation];
5
MKCoordinateRegion region = MKCoordinateRegionMakeWithDistance([mp coordinate] ,250,250);
6
7
[mv setRegion:region animated:YES];
8
}
上面的函数,是MKMapViewDelegate的一种代理的方法,它的功能是发送事件给当前的控制类,但是,我们必须在函数didFinishLaunchingWithOptions method:里面添加下面的代码:
1
self.mapView.
delegate
= self;
我们现在能在地图上看到一个点,MKCoordinateRegion创建了一个初始的区域在地图上,我们可以通过放大和缩小查看这个区域。
仿真器上定位的位置是,苹果公司在美国的位置。你必须在真机上调试才能看到我们当前的位置。
第三步:在地图上添加点:
继承 MKAnnotation这个类,我们创建一个叫做MapPoint的新类。实现如下:
01
#import <Foundation/Foundation.h>
02
#import <CoreLocation/CoreLocation.h>
03
#import <MapKit/MapKit.h>
04
05
@
interface
MapPoint : NSObject<MKAnnotation> {
06
07
NSString *title;
08
NSString *subTitle;
09
CLLocationCoordinate2D coordinate;
10
11
}
12
13
@property (nonatomic,
readonly
) CLLocationCoordinate2D coordinate;
14
@property (nonatomic,copy) NSString *title;
15
@property (nonatomic,copy) NSString *subTitle;
16
17
-(id) initWithCoordinate:(CLLocationCoordinate2D) c title:(NSString *) t subTitle:(NSString *) st;
18
19
@end
当地图获得新的位置时, MKMapViewDelegate的方法didUpdateUserLocation会被调用。在这个方法里,我们初始化点,并且把他们添加到地图上。
01
- (
void
)mapView:(MKMapView *)mv didUpdateUserLocation:(MKUserLocation *)userLocation
02
{
03
CLLocationCoordinate2D userCoordinate = userLocation.location.coordinate;
04
05
for
(
int
i = 1; i<=5;i++)
06
{
07
CGFloat latDelta = rand()*.035/RAND_MAX -.02;
08
CGFloat longDelta = rand()*.03/RAND_MAX -.015;
09
10
CLLocationCoordinate2D newCoord = { userCoordinate.latitude + latDelta, userCoordinate.longitude + longDelta };
11
MapPoint *mp = [[MapPoint alloc] initWithCoordinate:newCoord title:[NSString stringWithFormat:
@"Azam Home %d"
,i] subTitle:
@"Home Sweet Home"
];
12
[mv addAnnotation:mp];
13
[mp release];
14
15
}
16
}
如果想要实现callout的功能,比如弹出来的默认的文本框。我们想做的更加的有趣,在callout的左边或者右边添加一个小房子的图片。
第四步:实现默认点的图层:
The leftCalloutAccessoryView and rightCalloutAccessoryView这两个属性用来展示点的默认的属性。下面代码,展示了一张图片是如何在callout里面被显示出来的:
01
- (MKAnnotationView *)mapView:(MKMapView *)mv viewForAnnotation:(id <MKAnnotation>)annotation
02
{
03
if
([annotation isKindOfClass:[MKUserLocation
class
]])
04
return
nil;
05
06
NSString *annotationIdentifier =
@"PinViewAnnotation"
;
07
08
MKPinAnnotationView *pinView = (MKPinAnnotationView *) [mapView
09
dequeueReusableAnnotationViewWithIdentifier:annotationIdentifier];
10
11
12
if
(!pinView)
13
{
14
pinView = [[[MKPinAnnotationView alloc]
15
initWithAnnotation:annotation
16
reuseIdentifier:annotationIdentifier] autorelease];
17
18
[pinView setPinColor:MKPinAnnotationColorGreen];
19
pinView.animatesDrop = YES;
20
pinView.canShowCallout = YES;
21
22
UIImageView *houseIconView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:
@"house.png"
]];
23
pinView.leftCalloutAccessoryView = houseIconView;
24
[houseIconView release];
25
}
26
else
27
{
28
pinView.annotation = annotation;
29
}
30
31
return
pinView;
32
33
}
为了提升地图的表现效果,我们用id来保存地图的点的类型。也就是说,同一种点,用在地图的不同部分,重复利用同一种点,而不在重新的创建它。run 代码,在仿真器上点击绿的点,能够看到以下的结果:
上面的显示中,一张图片在点的callout里面显示出来了,但是图片的尺寸太大了。我们可以通过下面的代码调整图片大小:
1
UIImageView *houseIconView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:
@"house.png"
]];
2
[houseIconView setFrame:CGRectMake(0, 0, 30, 30)];
3
pinView.leftCalloutAccessoryView = houseIconView;
4
[houseIconView release];
尽管我们初始化了点的LameAnnotationViewcallout,我们没有改变点的样子,它是默认的样子。点能够被改变,通过建立一个点的类,重载DrawRect这个方法。继承,我们重新创建一个类,LameAnnotationView。以下是实现的代码:
01
#import "LameAnnotationView.h"
02
03
@implementation LameAnnotationView
04
05
- (id)initWithAnnotation:(id <MKAnnotation>)annotation reuseIdentifier:(NSString *)reuseIdentifier
06
{
07
self = [super initWithAnnotation:annotation reuseIdentifier:reuseIdentifier];
08
if
(self != nil)
09
{
10
CGRect frame = self.frame;
11
frame.size = CGSizeMake(60.0, 85.0);
12
self.frame = frame;
13
self.backgroundColor = [UIColor clearColor];
14
self.centerOffset = CGPointMake(-5, -5);
15
}
16
return
self;
17
}
18
19
-(
void
) drawRect:(CGRect)rect
20
{
21
[[UIImage imageNamed:
@"house.png"
] drawInRect:CGRectMake(30, 30.0, 30.0, 30.0)];
22
}
23
24
@end
为了使用我们创建的新点的类,用LameAnnotationView来替代默认的类,代码如下:
01
- (MKAnnotationView *)mapView:(MKMapView *)mv viewForAnnotation:(id <MKAnnotation>)annotation
02
{
03
if
([annotation isKindOfClass:[MKUserLocation
class
]])
04
return
nil;
05
06
NSString *annotationIdentifier =
@"PinViewAnnotation"
;
07
08
LameAnnotationView *pinView = (LameAnnotationView *) [mapView
09
dequeueReusableAnnotationViewWithIdentifier:annotationIdentifier];
10
11
12
if
(!pinView)
13
{
14
pinView = [[[LameAnnotationView alloc]
15
initWithAnnotation:annotation
16
reuseIdentifier:annotationIdentifier] autorelease];
17
18
//[pinView setPinColor:MKPinAnnotationColorGreen];
19
// pinView.animatesDrop = YES;
20
pinView.canShowCallout = YES;
21
22
UIImageView *houseIconView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:
@"house.png"
]];
23
[houseIconView setFrame:CGRectMake(0, 0, 30, 30)];
24
pinView.leftCalloutAccessoryView = houseIconView;
25
[houseIconView release];
26
}
27
else
28
{
29
pinView.annotation = annotation;
30
}
31
32
return
pinView;
33
34
}
我们在初始化点的视图时候,我们忽略了产生点的时候的特效。但是,这个部分的内容,可以通过特效的库,添加进来。以下代码是用来显示点被添加的时候,的效果。
01
- (
void
)mapView:(MKMapView *)mv didAddAnnotationViews:(NSArray *)views
02
{
03
04
// add the animation here
05
06
CGRect visibleRect = [mapView annotationVisibleRect];
07
08
for
(MKAnnotationView *view
in
views)
09
{
10
if
([view isKindOfClass:[LameAnnotationView
class
]])
11
{
12
CGRect endFrame = view.frame;
13
14
CGRect startFrame = endFrame;
15
16
startFrame.origin.y = visibleRect.origin.y - startFrame.size.height;
17
view.frame = startFrame;
18
19
20
[UIView beginAnimations:
@"drop"
context:NULL];
21
[UIView setAnimationDuration:2];
22
23
24
view.frame = endFrame;
25
[UIView commitAnimations];
26
}
27
}
28
29
30
MKAnnotationView *annotationView = [views objectAtIndex:0];
31
id<MKAnnotation> mp = [annotationView annotation];
32
MKCoordinateRegion region = MKCoordinateRegionMakeWithDistance([mp coordinate] ,5000,5000);
33
34
[mv setRegion:region animated:YES];
35
}
现在点击run,我们可以看到house点从天而降的下过,这个方法我们在 didAddAnnotationViews 方法里面实现过。
结论:
在这篇文章里面,我们学会了如何使用MapKit。同时,我们还证明了,如何去初始化点,初始化点的视图,特别是视图的显示效果,它能够增加用户的体验。
- iPhone开发:地图框架入门(一)
- iPhone开发入门(一)
- iPhone开发入门笔记(一)—快速入门
- Android 百度地图开发教程(一) 地图使用入门及地图表面覆盖物使用
- Android入门之——百度地图开发(一)
- iphone开发(一)
- iPhone开发之地图定位(CoreLocation和Mapkit框架)简易编程
- MapKit --- iOS中的地图框架 - iPhone手机开发技术文章
- 【UI初级 连载一】------iPhone开发入门
- 微信小程序地图开发入门(一)
- iphone开发 地图线路
- iphone开发 地图线路
- iphone开发 地图线路
- iPhone开发 地图线路
- iPhone开发 地图线路
- iphone开发 地图线路
- iPhone开发 地图线路
- iPhone开发 地图线路
- fork真的详解(太好的东西)
- File , Folder 与 Directory
- 引用 uboot在2440上移植
- web.xml文件的作用及基本配置
- Http协议相关状态码
- iPhone开发:地图框架入门(一)
- 分布式监控系统Ganglia
- 物理层传输格式的用法,关于TF,TFS,TFC,TFCS,TFI,TFCI
- android button 效果设计
- 25个让Java程序员更高效的Eclipse插件
- ConcurrentHashMap
- U3d插件——Swarm Object Manager分析(四)bullet和 Explosion 的实现
- click的i++ ------关于jquery的一些事
- 基于C# 的HTML解析器