2011-06-28 10 views
6

私は自分のアプリでMAPビューを持っており、注釈ピン(赤いピン)を地図ビューの中央に追加したいと思います。
ユーザーのスクロールマップビューのピンは、それに従ってセンターで調整する必要があります。
どうすればいいですか?マップビューの中心部の上方に位置するだけで通常のビューのではなく、実際のアノテーションを使用したい場合は
をすることができます、iPhoneのマップビューの中心に注釈を追加するには?

+0

それはあなたが中央を変更することにより、ピンの位置を変えていることを意味します。 –

+0

@Muhammad Zeeshan - はい、ユーザーがスクロールすると、赤いピン(注釈)がユーザーに表示されるマップビューの新しい中心に合わせて変更されます。 – dks1725

+0

注釈をマップの中心に置くようにしてください –

答えて

10

ありがとう:

  • が設定可能な座標プロパティと注釈クラスを使用します(前定義されたクラスMKPointAnnotationなど)。これにより、中心が変更されたときにアノテーションを削除して追加する必要がなくなります。
  • 確認マップビューのデリゲートプロパティが設定されていることを確認し(マップビューのregionDidChangeAnimatedデリゲートメソッドでcenterAnnotation
  • は、その(など、タイトル)座標を更新すると言う、プロパティにそれへの参照を保持
  • のviewDidLoad
  • で を注釈を作成します)

例:

@interface SomeViewController : UIViewController <MKMapViewDelegate> { 
    MKPointAnnotation *centerAnnotation; 
} 
@property (nonatomic, retain) MKPointAnnotation *centerAnnotation; 
@end 

@implementation SomeViewController 

@synthesize centerAnnotation; 

- (void)viewDidLoad { 
    [super viewDidLoad]; 

    MKPointAnnotation *pa = [[MKPointAnnotation alloc] init]; 
    pa.coordinate = mapView.centerCoordinate; 
    pa.title = @"Map Center"; 
    pa.subtitle = [NSString stringWithFormat:@"%f, %f", pa.coordinate.latitude, pa.coordinate.longitude]; 
    [mapView addAnnotation:pa]; 
    self.centerAnnotation = pa; 
    [pa release]; 
} 

- (void)mapView:(MKMapView *)mapView regionDidChangeAnimated:(BOOL)animated { 
    centerAnnotation.coordinate = mapView.centerCoordinate; 
    centerAnnotation.subtitle = [NSString stringWithFormat:@"%f, %f", centerAnnotation.coordinate.latitude, centerAnnotation.coordinate.longitude]; 
} 

- (void)dealloc { 
    [centerAnnotation release]; 
    [super dealloc]; 
} 

@end 

さて、これはスムーズに注釈を移動しなくなります。あなたがよりスムーズに移動する注釈が必要な場合は、マップビューにUIPanGestureRecognizerUIPinchGestureRecognizerを追加しても、ジェスチャーハンドラ内で注釈を更新することができます。

// (Also add UIGestureRecognizerDelegate to the interface.) 

    // In viewDidLoad: 
    UIPanGestureRecognizer *panGesture = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(handleGesture:)]; 
    panGesture.delegate = self; 
    [mapView addGestureRecognizer:panGesture]; 
    [panGesture release]; 

    UIPinchGestureRecognizer *pinchGesture = [[UIPinchGestureRecognizer alloc] initWithTarget:self action:@selector(handleGesture:)]; 
    pinchGesture.delegate = self; 
    [mapView addGestureRecognizer:pinchGesture]; 
    [pinchGesture release]; 

- (void)handleGesture:(UIGestureRecognizer *)gestureRecognizer 
{ 
    centerAnnotation.coordinate = mapView.centerCoordinate; 
    centerAnnotation.subtitle = [NSString stringWithFormat:@"%f, %f", centerAnnotation.coordinate.latitude, centerAnnotation.coordinate.longitude]; 
} 

- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer { 
    //let the map view's and our gesture recognizers work at the same time... 
    return YES; 
} 
+0

その完璧な作業に感謝しています。 – dks1725

+0

+1私はまだ解決策の上に「まだ」注釈を与えていませんが、地図ソリューションの上に表示します。 –

+0

誰かが速やかにこのコードを書くことができます:) –

4

アンナの答えはで中心に注釈を維持する巧妙なアプローチであります標準的な地図ビューの注釈を使用してマップします。しかし、コメント執筆者の1人が指摘するように、スクロールとピンチではずっと優れた状態が続いていますが、推奨されるアプローチは、アノテーションビューをマップビューのサブビューとして追加することです。それは何のように見えます。

@interface SHCenterPinMapViewController() <MKMapViewDelegate> 

@property (weak, nonatomic) IBOutlet MKMapView *mapView; 
@property (strong, nonatomic) MKPointAnnotation *centerAnnotaion; 
@property (strong, nonatomic) MKPinAnnotationView *centerAnnotationView; 

@end 

@implementation SHCenterPinMapViewController 

- (MKPointAnnotation *)centerAnnotaion 
{ 
    if (!_centerAnnotaion) { 
     _centerAnnotaion = [[MKPointAnnotation alloc] init]; 
    } 

    return _centerAnnotaion; 
} 

- (MKPinAnnotationView *)centerAnnotationView 
{ 
    if (!_centerAnnotationView) { 
     _centerAnnotationView = [[MKPinAnnotationView alloc] initWithAnnotation:self.centerAnnotaion 
                   reuseIdentifier:@"centerAnnotationView"]; 
    } 

    return _centerAnnotationView; 
} 

- (void)viewDidLoad 
{ 
    [super viewDidLoad]; 
    self.mapView.delegate = self; 
    [self.mapView addSubview:self.centerAnnotationView]; 
} 

-(void)viewDidAppear:(BOOL)animated 
{ 
    [super viewDidAppear:animated]; 
    [self moveMapAnnotationToCoordinate:self.mapView.centerCoordinate]; 
} 

// These are the constants need to offset distance between the lower left corner of 
// the annotaion view and the head of the pin 
#define PIN_WIDTH_OFFSET 7.75 
#define PIN_HEIGHT_OFFSET 5 

- (void)moveMapAnnotationToCoordinate:(CLLocationCoordinate2D) coordinate 
{ 
    CGPoint mapViewPoint = [self.mapView convertCoordinate:coordinate toPointToView:self.mapView]; 

    // Offset the view from to account for distance from the lower left corner to the pin head 
    CGFloat xoffset = CGRectGetMidX(self.centerAnnotationView.bounds) - PIN_WIDTH_OFFSET; 
    CGFloat yoffset = -CGRectGetMidY(self.centerAnnotationView.bounds) + PIN_HEIGHT_OFFSET; 

    self.centerAnnotationView.center = CGPointMake(mapViewPoint.x + xoffset, 
                mapViewPoint.y + yoffset); 
} 

- (void)mapView:(MKMapView *)mapView regionDidChangeAnimated:(BOOL)animated 
{ 
    self.centerAnnotaion.coordinate = mapView.centerCoordinate; 
    [self moveMapAnnotationToCoordinate:mapView.centerCoordinate]; 
} 

@end 

本当に唯一興味深いのは、あなたが左下隅とピンヘッドとの間の距離を考慮して一定量だけMKPinAnnotationViewを相殺しなければならないことではありませんします。私はこれらの資産に依存する定数をコードに持つのは好きではありません。誰かがもっと良い方法を見つけることができれば、私はすべて耳にします。

これを行うマップコントローラと、マップビューを使用してユーザーが場所を選択するのに関連する他のいくつかのものを使ってgithubプロジェクトを作成しました。ここでそれをチェックアウト:https://github.com/scottrhoyt/CenterPinMapViewController

+0

これは素晴らしいことです。ありがとうございました。どのようにあなたはピンにズームをロックすることができますか?ズームするときは、ピンをズームするだけです。 http://stackoverflow.com/questions/25577813/make-mkmapview-only-zoom-in-on-the-centercoordinate/25577949#25577949 –

0

スウィフトバージョンのクラスでは

:のviewDidLoadで

​​

:viewDidAppearで

if #available(iOS 9.0, *) { 
     centerAnnotationView.pinTintColor = customColor 
    } else { 
     // Fallback on earlier versions 
     centerAnnotationView.pinColor = MKPinAnnotationColor.Red 
    } 
self.view.addSubview(centerAnnotationView) 

self.moveMapAnnotationToCoordinate(self.mapView.centerCoordinate) 

を次に:位置の変化を利用するための

func moveMapAnnotationToCoordinate(locate : CLLocationCoordinate2D) { 
    let mapViewPoint : CGPoint = self.mapView.convertCoordinate(locate, toPointToView: self.mapView) 
    let pinWidth : CGFloat = 7.75 
    let pinHeight : CGFloat = 7 
    let xOffset : CGFloat = CGRectGetMidX(self.centerAnnotationView.bounds) - pinWidth 
    let yOffset : CGFloat = CGRectGetMidY(self.centerAnnotationView.bounds) - pinHeight 

    self.centerAnnotationView.center = CGPointMake(mapViewPoint.x - xOffset, mapViewPoint.y - yOffset) 
} 

、デリゲートCLLocationManagerDelegateを追加して:

func mapView(mapView: MKMapView, regionDidChangeAnimated animated: Bool) { 
    self.centerAnnotation.coordinate = self.mapView.centerCoordinate 
    self.moveMapAnnotationToCoordinate(self.mapView.centerCoordinate) 
} 
関連する問題