|
9 | 9 | #import "ViewController.h"
|
10 | 10 |
|
11 | 11 | @interface ViewController ()
|
12 |
| - |
| 12 | +@property (nonatomic, retain) CLLocationManager *locationManager; |
13 | 13 | @end
|
14 | 14 |
|
15 | 15 | @implementation ViewController
|
16 | 16 |
|
| 17 | +@synthesize locationManager = _locationManager; |
| 18 | + |
| 19 | +@synthesize headingFilterLabel = _headingFilterLabel; |
| 20 | +@synthesize headingOrientationLabel = _headingOrientationLabel; |
| 21 | +@synthesize headingAccuracyLabel = _headingAccuracyLabel; |
| 22 | +@synthesize magneticHeadingLabel = _magneticHeadingLabel; |
| 23 | +@synthesize trueHeadingLabel = _trueHeadingLabel; |
| 24 | +@synthesize xLabel = _xLabel; |
| 25 | +@synthesize yLabel = _yLabel; |
| 26 | +@synthesize zLabel = _zLabel; |
| 27 | +@synthesize arrowLabel = _arrowLabel; |
| 28 | +@synthesize northSegment = _northSegment; |
| 29 | + |
17 | 30 | - (void)viewDidLoad
|
18 | 31 | {
|
19 | 32 | [super viewDidLoad];
|
20 |
| - // Do any additional setup after loading the view, typically from a nib. |
| 33 | + |
| 34 | + // ヘディングの設定 |
| 35 | + CLLocationDegrees headingFilter = kCLHeadingFilterNone; // 常に |
| 36 | + CLDeviceOrientation headingOrientation = CLDeviceOrientationPortrait; // 上部を基準とする |
| 37 | + |
| 38 | + // インスタンスの生成 |
| 39 | + _locationManager = [[CLLocationManager alloc] init]; |
| 40 | + // ヘディングが有効ならば設定をして開始 |
| 41 | + if ([CLLocationManager headingAvailable]) { |
| 42 | + _locationManager.delegate = self; |
| 43 | + _locationManager.headingFilter = headingFilter; |
| 44 | + _locationManager.headingOrientation = headingOrientation; |
| 45 | + [_locationManager startUpdatingHeading]; |
| 46 | + |
| 47 | + // Viewのスイッチの設定 |
| 48 | + self.northSegment.selectedSegmentIndex = 1; // 磁北を選択 |
| 49 | + self.northSegment.enabled = YES; |
| 50 | + } |
| 51 | + |
| 52 | + /* Viewに反映 */ |
| 53 | + self.headingFilterLabel.text = [NSString stringWithFormat:@"%lf", headingFilter]; |
| 54 | + self.headingOrientationLabel.text = [self deviceOrientationToString:headingOrientation]; |
21 | 55 | }
|
22 | 56 |
|
23 | 57 | - (void)viewDidUnload
|
24 | 58 | {
|
| 59 | + _locationManager.delegate = nil; |
| 60 | + |
| 61 | + self.locationManager = nil; |
| 62 | + self.headingFilterLabel = nil; |
| 63 | + self.headingOrientationLabel = nil; |
| 64 | + self.headingAccuracyLabel = nil; |
| 65 | + self.magneticHeadingLabel = nil; |
| 66 | + self.trueHeadingLabel = nil; |
| 67 | + self.xLabel = nil; |
| 68 | + self.yLabel = nil; |
| 69 | + self.zLabel = nil; |
| 70 | + self.arrowLabel = nil; |
| 71 | + self.northSegment = nil; |
| 72 | + |
25 | 73 | [super viewDidUnload];
|
26 |
| - // Release any retained subviews of the main view. |
| 74 | +} |
| 75 | + |
| 76 | +- (void)dealloc |
| 77 | +{ |
| 78 | + _locationManager.delegate = nil; |
| 79 | + |
| 80 | + [_locationManager release]; |
| 81 | + [_headingFilterLabel release]; |
| 82 | + [_headingOrientationLabel release]; |
| 83 | + [_headingAccuracyLabel release]; |
| 84 | + [_magneticHeadingLabel release]; |
| 85 | + [_trueHeadingLabel release]; |
| 86 | + [_xLabel release]; |
| 87 | + [_yLabel release]; |
| 88 | + [_zLabel release]; |
| 89 | + [_northSegment release]; |
| 90 | + |
| 91 | + [super dealloc]; |
27 | 92 | }
|
28 | 93 |
|
29 | 94 | - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
|
30 | 95 | {
|
31 |
| - if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone) { |
32 |
| - return (interfaceOrientation != UIInterfaceOrientationPortraitUpsideDown); |
33 |
| - } else { |
34 |
| - return YES; |
| 96 | + return (interfaceOrientation == UIInterfaceOrientationPortrait); |
| 97 | +} |
| 98 | + |
| 99 | +/* セグメントが変更された */ |
| 100 | +- (IBAction)northSegmentChanged:(UISegmentedControl *)sender { |
| 101 | + switch (sender.selectedSegmentIndex) { |
| 102 | + case 0: // 停止 |
| 103 | + NSLog(@"%s | stopUpdatingLocation & stopUpdatingHeading", __PRETTY_FUNCTION__); |
| 104 | + [_locationManager stopUpdatingLocation]; |
| 105 | + [_locationManager stopUpdatingHeading]; |
| 106 | + break; |
| 107 | + case 1: // 磁北 |
| 108 | + NSLog(@"%s | stopUpdatingLocation & startUpdatingHeading", __PRETTY_FUNCTION__); |
| 109 | + [_locationManager stopUpdatingLocation]; |
| 110 | + [_locationManager startUpdatingHeading]; |
| 111 | + break; |
| 112 | + case 2: // 真北 |
| 113 | + NSLog(@"%s | startUpdatingLocation & startUpdatingHeading", __PRETTY_FUNCTION__); |
| 114 | + _locationManager.distanceFilter = kCLDistanceFilterNone; |
| 115 | + _locationManager.desiredAccuracy = kCLLocationAccuracyBest; |
| 116 | + [_locationManager startUpdatingLocation]; |
| 117 | + [_locationManager startUpdatingHeading]; |
| 118 | + break; |
| 119 | + } |
| 120 | +} |
| 121 | + |
| 122 | +#pragma mark - CLLocationManagerDelegate methods |
| 123 | + |
| 124 | +/* ヘディング情報が更新された */ |
| 125 | +- (void)locationManager:(CLLocationManager *)manager didUpdateHeading:(CLHeading *)newHeading |
| 126 | +{ |
| 127 | + if (newHeading.headingAccuracy < 0) { |
| 128 | + return; // 正しく取得できていない |
| 129 | + } |
| 130 | + |
| 131 | + // 磁北か真北か |
| 132 | + CLLocationDirection heading = (self.northSegment.selectedSegmentIndex == 1) ? newHeading.magneticHeading : newHeading.trueHeading; |
| 133 | + // 値が正しくなければ0度で固定 |
| 134 | + if (heading < 0) { |
| 135 | + heading = 0; |
| 136 | + } |
| 137 | + |
| 138 | + /* Viewに反映 */ |
| 139 | + CGFloat radius = (heading / 180) * M_PI; |
| 140 | + self.arrowLabel.transform = CGAffineTransformMakeRotation(-radius); // 回転方向が逆なので符号を反転 |
| 141 | + |
| 142 | + self.headingAccuracyLabel.text = [NSString stringWithFormat:@"%lf", newHeading.headingAccuracy]; |
| 143 | + self.magneticHeadingLabel.text = [NSString stringWithFormat:@"%lf", newHeading.magneticHeading]; |
| 144 | + self.trueHeadingLabel.text = [NSString stringWithFormat:@"%lf", newHeading.trueHeading]; |
| 145 | + self.xLabel.text = [NSString stringWithFormat:@"%lf", newHeading.x]; |
| 146 | + self.yLabel.text = [NSString stringWithFormat:@"%lf", newHeading.y]; |
| 147 | + self.zLabel.text = [NSString stringWithFormat:@"%lf", newHeading.z]; |
| 148 | +} |
| 149 | + |
| 150 | +/* コンパスの調整を画面に表示するかどうか */ |
| 151 | +- (BOOL)locationManagerShouldDisplayHeadingCalibration:(CLLocationManager *)manager |
| 152 | +{ |
| 153 | + return YES; |
| 154 | +} |
| 155 | + |
| 156 | +/* 下部スイッチの変更のため、位置情報サービスのオン・オフの変更を受け取る */ |
| 157 | +- (void)locationManager:(CLLocationManager *)manager didChangeAuthorizationStatus:(CLAuthorizationStatus)status |
| 158 | +{ |
| 159 | + if ([CLLocationManager headingAvailable]) { |
| 160 | + // ヘディングが有効な場合のみ |
| 161 | + if (status == kCLAuthorizationStatusAuthorized || status == kCLAuthorizationStatusNotDetermined) { |
| 162 | + // 真北を有効化 |
| 163 | + [self.northSegment setEnabled:YES forSegmentAtIndex:2]; |
| 164 | + } else { |
| 165 | + // それ以外は無効化 |
| 166 | + if (self.northSegment.selectedSegmentIndex == 2) { |
| 167 | + // 真北が選ばれていたならば、磁北に移動 |
| 168 | + self.northSegment.selectedSegmentIndex = 1; |
| 169 | + } |
| 170 | + [self.northSegment setEnabled:NO forSegmentAtIndex:2]; |
| 171 | + } |
| 172 | + } |
| 173 | +} |
| 174 | + |
| 175 | +#pragma mark - private methods |
| 176 | + |
| 177 | +/* デバイスの向きを文字列に変換する */ |
| 178 | +- (NSString *)deviceOrientationToString:(CLDeviceOrientation)orientation |
| 179 | +{ |
| 180 | + switch (orientation) { |
| 181 | + case CLDeviceOrientationUnknown: |
| 182 | + return @"Unknown"; |
| 183 | + case CLDeviceOrientationPortrait: |
| 184 | + return @"Portrait"; |
| 185 | + case CLDeviceOrientationPortraitUpsideDown: |
| 186 | + return @"UpsideDown"; |
| 187 | + case CLDeviceOrientationLandscapeLeft: |
| 188 | + return @"LandscapeLeft"; |
| 189 | + case CLDeviceOrientationLandscapeRight: |
| 190 | + return @"LandscapeRight"; |
| 191 | + case CLDeviceOrientationFaceUp: |
| 192 | + return @"FaceUp"; |
| 193 | + case CLDeviceOrientationFaceDown: |
| 194 | + return @"FaceDown"; |
35 | 195 | }
|
36 | 196 | }
|
37 | 197 |
|
|
0 commit comments