1

こんにちは。

locationManager と CLGeocoder のチュートリアルを完了しようとしていますが、クラスを介してこれらがどのように相互作用するかを理解するのに苦労しています。

説明するために、チュートリアルに従って現在の場所を表示しました。現在、CLGeocoder にその場所に関する情報を返させようとしていますが、locationManager が別のクラスにあるため、問題が発生しています。私の問題は、カスタム クラスと、View Controller がそれらをすべて結び付ける方法を理解することです。

これまでの私のコードは次のとおりです。

appdelegate.h

#import <UIKit/UIKit.h>
#import "LocationGetter.h"
#import <UIKit/UIKit.h>
#import "LocationGetter.h"

@class ViewController;

@interface AppDelegate : UIResponder <UIApplicationDelegate>

@property (retain, nonatomic) UIWindow *window;

@property (retain, nonatomic) ViewController *viewController;

@property (nonatomic, strong) CLLocation *lastKnownLocation;


@end

appdelegate.m

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:       (NSDictionary *)launchOptions
{
    self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
    // Override point for customization after application launch.
    self.viewController = [[ViewController alloc] initWithNibName:@"ViewController"     bundle:nil];
    self.window.rootViewController = self.viewController;
    [self.window makeKeyAndVisible];
    self.locationGetter = [[LocationGetter alloc] init];
    self.locationGetter.delegate = self;
    [self.locationGetter startUpdates];

クラス locationgetter.h

#import <Foundation/Foundation.h>
#import <CoreLocation/CoreLocation.h>

@protocol LocationGetterDelegate <NSObject>
@required
- (void) newPhysicalLocation:(CLLocation *)location;
@end

@interface LocationGetter : NSObject

-(void)startUpdates;

@property (nonatomic, weak) id<LocationGetterDelegate>delegate;



@end

locationgetter.m

#import "LocationGetter.h"
#import <CoreLocation/CoreLocation.h>

@interface LocationGetter () <CLLocationManagerDelegate>

@property (nonatomic, strong) CLLocationManager *locationManager;

@end

@implementation LocationGetter
//@synthesize geoCoder;


bool didUpdate = NO;

-(void) startUpdates{
    NSLog(@"Starting Location Updates");

    if (self.locationManager == nil)
        self.locationManager = [[CLLocationManager alloc]init];
    self.locationManager.delegate = self;

    self.locationManager.desiredAccuracy = kCLLocationAccuracyKilometer;
    [self.locationManager startUpdatingLocation];



}

- (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error
{
    UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Error" message:@"Your location could not be determined." delegate:nil cancelButtonTitle:@"OK" otherButtonTitles: nil];
    [alert show];
}

// Delegate method from the CLLocationManagerDelegate protocol.
- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation
{
    if (didUpdate)
        return;

    didUpdate = YES;
    // Disable future updates to save power.
    [manager stopUpdatingLocation];

    // let our delegate know we're done
    [_delegate newPhysicalLocation:newLocation];

}



@end

さて、ここで問題です...

どこかに CLGeocoder プロパティと、CLGeocoder を起動するボタンからのアクションを配置する必要があります。これをView Controllerに入れてみました

@property (strong, nonatomic) IBOutlet CLGeocoder *geoCoder;

- (IBAction)geoCodeLocation:(id)sender;

これはviewcontroller.mにあります

- (IBAction)geoCodeLocation:(id)sender {
    NSLog(@"hello %@,", sender); 
[self.geoCoder reverseGeocodeLocation: locationManager.location completionHandler: 
 ^(NSArray *placemarks, NSError *error) {
}

しかし、私のやり方では、locationManager が見つかりません。ロケーションが AppDelegate.M にあるためだと思います。これは私の問題です。viewcontroller に入ると、場所を表示する方法がわかりません。私は、変数を渡すか、グローバル変数を作成するだけの ac# バックグラウンドから来ました。

誰かがIOSでオブジェクトを通信するための最良の方法を説明できますか. 自分自身をよりよく説明する必要がある場合はお知らせください。

ありがとう!!!

4

1 に答える 1

1

あなたの要件が何であるかはわかりませんが、アプリ内の 1 つのビュー コントローラーで位置情報のみを処理する必要がある場合は、LocationGetterLocationGetterDelegateクラスを省略し、CLLocationManagerを の ivar として使用して、 にメソッドをViewController実装するだけです。CLLocationManagerDelegateViewController

このようにするCLLocationManagerと、アプリ内のデリゲートへのアクセスの問題が解消されるため、次のことができます。

[self.geocoder reverseGeocodeLocation: self.locationManager.location completionHandler: 
^(NSArray *placemarks, NSError *error) { //completion stuff
}];

Apple は、「GeocoderDemo」デモ プロジェクトでこれを行っています。ここCLLocationManagerから入手できます。実際、各タブ VC には異なるインスタンスがあります。(3 インスタンス)。あなたのやり方が少しきれいでエレガントであることは理解していますが、平均的なアプリではおそらくやり過ぎです。一般的に、シンプルなほど優れています。

CLLocationManagerとはいえ、カスタム クラスにラップされたアプリ デリゲートが絶対に必要な場合は、メソッドViewController.mを次のように変更できます。

- (IBAction)geoCodeLocation:(id)sender 
{
   AppDelegate *delegate = [[UIApplication sharedApplication]delegate];
   //probably want some error handling here to deal with possibility that 
   //delegate.lastKnownLocation is nil.
   [self.geoCoder reverseGeocodeLocation: delegate.lastKnownLocation completionHandler: 
   ^(NSArray *placemarks, NSError *error) {
        //completion stuff
   }];
}

(明らかに#import "AppDelegate.h"、これを行うクラスで必要になります)。

マイナーポイント:

- UI 要素ではないため、 CLGeocoderanを作成しても意味がありません。IBOutlet

-アプリのデリゲートで#importingUIKitLocationGetter2 回実行しています (これはタイプミスである可能性があります!)。

于 2013-03-03T20:25:33.837 に答える