读书频道 > 网站 > 网页设计 > iOS 5编程入门经典(第3版)——开发iPhone与iPad应用
20.2.4 旋转地图
12-11-08    奋斗的小年轻
收藏    我要投稿   
本书面向iPhone和iPad开发初学者,涵盖了iOS开发的各个主题。本书的编写方式是渐进式的,这样读者就不会由于细节过多而疲于奔命。我认为最好的学习方式就是去实践,因此全书大量的试一试首先会介绍如何构建某个应...立即去当当网订购

前一节展示了如何根据从Core Location框架获得的方向信息以编程方式旋转指南针图像。基于相同的概念,也可以在设备的方向发生变化时旋转地图。当使用地图进行方向导航时,这一点十分有用。下面的“试一试”演示了如何基于方向旋转地图。

 试一试       旋转地图

(1) 使用LBS项目,选择LBSViewController.xib文件,在Interface Builder中编辑它。

(2) 从Object Library中拖放一个View视图,通过Size Inspector窗口设置其大小和位置,具体的设置如下所示(也可以参考图20-15):


 

● X:0

● Y:130

● W:320

● H:330

(3) 在View视图的Attributes Inspector窗口中,选中Clip Subviews复选框,如图20-16所示。


 

(4) 在Xcode中,将如下粗体代码添加到LBSViewController.h文件中:
#import <UIKit/UIKit.h>
#import <CoreLocation/CoreLocation.h>
#import <MapKit/MapKit.h>

@interface LBSViewController : UIViewController
<CLLocationManagerDelegate, MKMapViewDelegate> {
    IBOutlet UITextField *accuracyTextField;
    IBOutlet UITextField *latitudeTextField;
    IBOutlet UITextField *longitudeTextField;
    CLLocationManager *lm;
    MKMapView *mapView;
   
    IBOutlet UIImageView *compass;
    IBOutlet UILabel *heading;
    IBOutlet UIView *viewForMap;   
}

@property (retain, nonatomic) UITextField *accuracyTextField;
@property (retain, nonatomic) UITextField *latitudeTextField;
@property (retain, nonatomic) UITextField *longitudeTextField;

@property (nonatomic, retain) UIImageView *compass;
@property (nonatomic, retain) UILabel *heading;
@property (nonatomic, retain) UIView *viewForMap;

@end

(5) 在Interface Builder中,按住Control键并将File’s Owner项拖放到新添加的View视图上。选择viewForMap。

(6) 将如下粗体代码添加到LBSViewController.m文件中:
#import "LBSViewController.h"

@implementation LBSViewController

@synthesize latitudeTextField;
@synthesize longitudeTextField;
@synthesize accuracyTextField;

@synthesize compass;
@synthesize heading;

@synthesize viewForMap;

- (void)viewDidLoad
{
    lm = [[CLLocationManager alloc] init];
    lm.delegate = self;
    lm.desiredAccuracy = kCLLocationAccuracyBest;
    lm.distanceFilter = kCLDistanceFilterNone;
    [lm startUpdatingLocation];
   
    //---get the compass readings---
    [lm startUpdatingHeading];
   
    //---display the map in a region---   
    mapView = [[MKMapView alloc]              
                  initWithFrame:CGRectMake(-90, -85, 500,500)];

    //initWithFrame:CGRectMake(0, 130, 320, 340)];   
    mapView.delegate = self;
    mapView.mapType = MKMapTypeHybrid;   

    // [self.view addSubview:mapView];
    [self.viewForMap addSubview:mapView];

    [super viewDidLoad];
}

- (void)locationManager:(CLLocationManager *)manager
       didUpdateHeading:(CLHeading *)newHeading {
   
    heading.text = [NSString stringWithFormat:@"%.2f degrees",
                       newHeading.magneticHeading];
   
    //---headings is in degrees---
    double d = newHeading.magneticHeading;
   
    //----convert degrees to radians----
    double radians = d / 57.2957795;
   
    compass.transform = CGAffineTransformMakeRotation(-radians);

    //---rotate the map---
    mapView.transform = CGAffineTransformMakeRotation(-radians);

}

- (void)dealloc {
    [viewForMap release];
    [compass release];   
    [heading release];       
    [mapView release];
    [lm stopUpdatingLocation];
    [lm release];
    [latitudeTextField release];
    [longitudeTextField release];
    [accuracyTextField release];
    [super dealloc];

(7) 将应用程序部署到实际的iPhone设备上。注意观察,在旋转iPhone时,地图也会发生旋转。

示例说明

地图旋转的原理其实十分简单。你可能一开始认为:最简单的方法是对mapView应用变换,但是这样做不只会旋转地图,而且还会旋转整个矩形,如图20-17所示。


 

可以采用的技巧是把mapView嵌入到另一个View视图中,然后在这个View视图中旋转它。因此,在View窗口中添加了另一个View视图(viewForMap),并将其设置为Clip Subviews。这样一来,所有添加到View窗口中的视图便都不会在窗口的边界以外显示。

现在不是按照原始尺寸显示地图,而是将它设置为最小459.67 x 459.67像素。这是地图中可视矩形的对角长。为简单起见,将这个最小值舍入为500×500像素。

现在把mapView添加到viewForMap而不是self.view中:
    // [self.view addSubview:mapView];
    [self.viewForMap addSubview:mapView];

回忆一下,mapView的初始位置为(0,130):
    //---display the map in a region---
    mapView = [[MKMapView alloc]
                 initWithFrame:CGRectMake(0, 130, 320, 340)];

现在必须将其改为(-90,-85):
    //---display the map in a region---   
    mapView = [[MKMapView alloc]              
                 initWithFrame:CGRectMake(-90, -85, 500,500)];
                 //initWithFrame:CGRectMake(0, 130, 320, 340)];

图20-18显示了如何得出新的坐标(-90,-85)。记住,在把一个视图添加到另一个视图中时,指定的坐标总是相对于所添加到的视图来计算的。在本例中,参考点(0,0)位于viewForMap视图中。


 

最后,为了旋转地图,对mapView应用CGAffineTransformMakeRotation()方法:
    //---rotate the map---
    mapView.transform = CGAffineTransformMakeRotation(-radians);

注意:在iOS 5中,也可以使用新增的“setUserTrackingMode:animated:”方法在地图上自动显示一个蓝色圆圈,用来表示用户的位置:
[mapView setUserTrackingMode:MKUserTrackingModeFollowWithHeading
       animated:YES];

MKUserTrackingModeFollowWithHeading常量会使地图随用户一起移动(如图20-19所示),以及基于方向信息自动旋转。


 

 

点击复制链接 与好友分享!回本站首页
分享到: 更多
您对本文章有什么意见或着疑问吗?请到论坛讨论您的关注和建议是我们前行的参考和动力  
上一篇:1.3 功能
下一篇:1.5 小结
相关文章
图文推荐
JavaScript网页动画设
1.9 响应式
1.8 登陆页式
1.7 主题式
排行
热门
文章
下载
读书

关于我们 | 联系我们 | 广告服务 | 投资合作 | 版权申明 | 在线帮助 | 网站地图 | 作品发布 | Vip技术培训
版权所有: 红黑联盟--致力于做最好的IT技术学习网站