3

MapAnnotationユーザーがクリックした特定の詳細を取得しようとしています。詳細はplistファイルから取得されます。この関数では、これを使用して使用- (void)mapView:(MKMapView *)mapView didSelectAnnotationView:(MKAnnotationView *)view; しました。特定をクリックすると、annotation場所の詳細がMapas からフェッチされ"Pune, Maharashtra, India @ <+18.50565666,+73.85559082> +/- 0.00m"、plist の値がチェックされません。これらの値を plist の属性として各場所の緯度経度として指定した後でも、誰でも解決できますか私の問題?

私のplistファイルの詳細:

2013-02-18 12:16:56.039 MapView[9407:13d03] {
contents = "This Fish will be Found Rarely in South Asia";
imagesName = "kfish.jpg";
latlong = "Bangalore, Karnataka, India @ <+12.98333330,+77.58333330> +/- 0.00m";
listName = kFish;
location = "Bangalore, Karnataka, India";
}
2013-02-18 12:16:56.039 MapView[9407:13d03] {
contents = "This Fish will be Found Rarely in South Asia";
imagesName = "wallfish.png";
latlong = "Delhi, India @ <+28.59100531,+77.08826373> +/- 0.00m";
listName = WallFish;
location = "Delhi, India";
}
2013-02-18 12:16:56.039 MapView[9407:13d03] {
contents = "This Fish will be Found Rarely in South Asia";
imagesName = "fish.jpg";
latlong = "Chennai, Tamil Nadu, India @ <+13.07983465,+80.24625757> +/- 0.00m";
listName = Fish;
location = "Chennai,TamilNadu,India";
}

2013-02-18 12:16:56.039 MapView[9407:13d03] {
contents = "This Fish will be Found Rarely in South Asia";
imagesName = "bluefish.jpg";
latlong = "Mumbai, Maharashtra, India @ <+18.99460885,+72.82287598> +/- 0.00m";
listName = BlueFish;
location = "Mumbai, Maharashtra, India";
}

2013-02-18 12:16:56.040 MapView[9407:13d03] {
contents = "This Fish will be Found Rarely in South Asia";
imagesName = "Rarefish.jpg";
latlong = "Chennai, Tamil Nadu, India @ <+13.07983465,+80.24625757> +/- 0.00m";
listName = RareFish;
location = "Chennai,TamilNadu,India";
}

私のコーディング:

- (void)geocodeRequest
{
CLGeocoder *geocoder = [[CLGeocoder alloc]init];
for (int i = 0; i < total; i++) {
    NSString *address = [allValues objectAtIndex:i] ;

            [geocoder geocodeAddressString:address completionHandler:^(NSArray *placemarks, NSError *error) {
                        CLPlacemark *geocodedPlacemark = [placemarks objectAtIndex:0];
                        MKPlacemark *placemark = [[MKPlacemark alloc] initWithCoordinate:geocodedPlacemark.location.coordinate addressDictionary:geocodedPlacemark.addressDictionary];

                        int zoomLevel=20;
                        MKCoordinateRegion region=MKCoordinateRegionMake(geocodedPlacemark.location.coordinate, MKCoordinateSpanMake(zoomLevel,zoomLevel));
                        [self.mapView addAnnotation:placemark];
                        [self.mapView setRegion:region animated:YES];
                        [self.mapView setZoomEnabled:YES];
                                  }];

}


-(void)mapView:(MKMapView *)mapView didSelectAnnotationView:(MKAnnotationView *)view{
    total = self.arrayImages.count;
NSArray *newIndex = [mapView selectedAnnotations];
NSLog(@"sel :%@",newIndex);

    for (index = 0; index < total; index++) {
        dict = [self.arrayImages objectAtIndex:index];
        NSLog(@"%@",dict);

        if (latlong == newIndex) {

            CGRect rec = CGRectMake(0, 0, 250, 250);
            [self setView:[[[UIView alloc] initWithFrame:rec] autorelease]];
            [[self view] setBackgroundColor:[UIColor whiteColor]];
            UIImage *img = [UIImage imageNamed:[dict objectForKey:@"imagesName"]];

            UIImageView *im = [[UIImageView alloc] initWithImage:img];
            UILabel *lab1 = [[UILabel alloc] init];
            UITextView *detailsView = [[UITextView alloc] init];
            lab1.text = [NSString stringWithFormat:[dict objectForKey:@"listName"]];
            detailsView.text = [NSString stringWithFormat:[dict objectForKey:@"contents"]];
            detailsView.editable = NO;
            detailsView.bounds = CGRectMake(20, 20, 150, 150);
            detailsView.frame = CGRectMake(210, 720, 390, 350);
            detailsView.font = [UIFont systemFontOfSize:24];

            lab1.bounds = CGRectMake(20, 20, 150, 150);
            lab1.frame = CGRectMake(360, 600, 90, 50);
            lab1.font = [UIFont systemFontOfSize:24];
            im.bounds = CGRectMake(10, 10, 50, 50);
            im.frame = CGRectMake(200, 120, 370, 450);

        [UIView transitionWithView:[self view] duration:1.5
                           options:UIViewAnimationOptionTransitionCurlUp
                        animations:^ { [[self view] addSubview:im];
                                       [[self view] addSubview:lab1];
                                       [[self view] addSubview:detailsView];

         }completion:nil];
        }
    }


}

MapView は問題なく動作しますが、選択した場所をフェッチするだけでは機能しません。

前もって感謝します。

4

1 に答える 1

3

あなたのdidSelectAnnotationView方法では、あなたはあなたのを繰り返しているようarrayImagesに見え、その人を探していますlatlong == newIndex。いくつかの考え:

  1. オブジェクトを比較するために等式演算子を使用する==ことは、一般的に賢明な手法ではありません。マップビューの注釈が同じオブジェクトであるという保証はありません(それらのプロパティがを使用してcopyいる場合、オブジェクトのアドレスとオブジェクトのアドレスが異なる可能性があるため、同じではありません)。そして、それがたまたま機能したとしても、それは非常に信頼できる方法ではありません。

  2. とにかく、等式演算子が機能したとしても、私があなたの論理に従うかどうかはよくありません。なぜなら、geocodeRequestあなたは新しいMKPlacemark、からを作成しているのですallValuesが、didSelectAnnotationViewあなたはそれを。と比較しているからですarrayImages。そして、のあなたのifステートメントはとをdidSelectAnnotationViewlatlongnewIndexいます(前者はあなたが設定しているのを見ていません、後者は注釈の配列です)。それは私には意味がありません。それらがどのように一致する可能性があるのか​​わかりません。

  3. MKPlacemarkただし、適切な解決策は、マップにを追加せずにリストを反復処理してdidSelectAnnotationView一致を探すことではなく、必要なすべてのプロパティを使用して独自のアノテーションクラスを作成することであるため、これら2つの前のポイントは関係ありません。ユーザーが注釈ビューをタップしたときに取得できます。または、少なくとも、独自のアノテーションサブクラスを用意し、配列から特定の詳細を検索するために使用できるプロパティを定義します。どちらのアプローチでも機能します。ただし、重要なのは、一致するものを探してオブジェクトを反復処理するのではなく、すぐに見つけるために必要なすべてを備えたカスタムアノテーションを定義することです。

    カスタム注釈の例については、 『 Location Awareness Programming Guide』の「 Defining aCustomAnnotationObject 」セクションを参照してください。必要と思われるすべての追加プロパティを使用して独自のアノテーションサブクラスを定義したら、(a)を変更して、 ;ではなく新しいアノテーションサブクラスのインスタンスを作成します。(b)(のプロパティである)から必要なデータを取得するように変更します。そうすることで、一致する可能性のあるアノテーションのリストを反復処理するという頭痛の種を完全に排除できます。geocodeRequestMKPlacemarkdidSelectAnnotationViewannotationannotationView

参考までに、別のSO回答では、コールアウト、ポップオーバーなどを処理するためのオプションの例をいくつか示します。そのため、あなたにとっても役立つ背景があるかもしれません。ここではカスタムアノテーションを使用していませんが、MapKitとの統合に関するアイデアが得られるかもしれません。


この方法を説明しましょう。マップに注釈を付けたいが、追加のプロパティを追跡したいとします。まず、追加のプロパティを持つ注釈カスタムクラスを定義します。(これをサブクラス化しMKPointAnnotationて、生活を少し楽にします。)

@interface CustomAnnotation : MKPointAnnotation

@property (nonatomic) NSUInteger index;
@property (strong, nonatomic) NSString *property1;
@property (strong, nonatomic) NSString *property2;
@property (strong, nonatomic) NSString *property3;

@end

ここで、アノテーションをマップビューに追加する場合は、カスタムアノテーションクラスを使用して、必要なプロパティを設定してください。数値インデックスを配列に保存するか、気になる実際のプロパティを保存するか、またはその両方を行うことができます。

CustomAnnotation *annotation = [[CustomAnnotation alloc] init];

// set the MKPointAnnotation standard properties

annotation.title = item.name;
annotation.coordinate = item.placemark.coordinate;

// set my custom properties

annotation.index = idx;
annotation.property1 = ...;
annotation.property2 = ...;
annotation.property3 = ...;

// now add the annotation to the map view

[annotations addObject:annotation];

または、のすべてのプロパティを利用したい場合MKPlacemarkは、次のようにすることができます。

@interface CustomAnnotation : MKPlacemark

@property (strong, nonatomic) NSString *title; // MKPlacemark doesn't have title, so let's add our own property for that
@property (nonatomic) NSUInteger index;
@property (strong, nonatomic) NSString *property1;
@property (strong, nonatomic) NSString *property2;
@property (strong, nonatomic) NSString *property3;

@end

そして、を作成するのと同じように注釈を作成しますがMKPlacemark、ここでも、カスタムプロパティを設定します。

CustomAnnotation *annotation = [[CustomAnnotation alloc] initWithPlacemark:item.placemark];

// set my custom properties

annotation.title = item.name;
annotation.index = idx;
annotation.property1 = ...;

[annotations addObject:annotation];

これで、注釈ビューを選択すると、それに応じて処理できます。

- (void)mapView:(MKMapView *)mapView didSelectAnnotationView:(MKAnnotationView *)view
{
    if ([view.annotation isKindOfClass:[CustomAnnotation class]])
    {
        CustomAnnotation *annotation = view.annotation;

        // note, I don't have to iterate through any arrays to figure out which
        // annotation I'm dealing with; I can just look at my custom properties

        NSLog(@"index = %d; property1 = %@", annotation.index, annotation.property1);

        // now do whatever you want with that annotation; I could look up the
        // annotations's details by using the custom `index` property I defined,
        // or if I defined my annotations to store all of the detail properties
        // I needed, I can just access them directly
    }
}

余談ですが、を使用するのではなくdidSelectAnnotationView、より標準的な動作を採用しMKMapView、標準のコールアウトバブルを表示し、適切なコールアウトバブルアクセサリを設定してから、そのコールアウトアクセサリのクリックを処理することをお勧めします。

- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id<MKAnnotation>)annotation
{
    if (![annotation isKindOfClass:[CustomAnnotation class]])
        return nil;

    MKAnnotationView *annotationView = [[MKPinAnnotationView alloc] initWithAnnotation:annotation
                                                                       reuseIdentifier:@"CustomAnnotationView"];
    annotationView.canShowCallout = YES;
    annotationView.rightCalloutAccessoryView = [UIButton buttonWithType:UIButtonTypeDetailDisclosure];
    
    return annotationView;
}

- (void)mapView:(MKMapView *)mapView annotationView:(MKAnnotationView *)view calloutAccessoryControlTapped:(UIControl *)control
{
    if (![view.annotation isKindOfClass:[CustomAnnotation class]])
        return;

    CustomAnnotation *annotation = view.annotation;

    // note, I don't have to iterate through any arrays to figure out which
    // annotation I'm dealing with; I can just look at my custom properties

    NSLog(@"index = %d; property1 = %@", annotation.index, annotation.property1);

    // now do whatever you want with that annotation; I could look up the
    // annotations's details by using the custom `index` property I defined,
    // or if I defined my annotations to store all of the detail properties
    // I needed, I can just access them directly
}
于 2013-02-18T08:24:40.503 に答える