0

私のアプリには、ユーザーが画面を押すことで注釈を追加できる mapView があります。アノテーションが mapView にドロップされると、それらはシングルトンの可変配列に追加されます。注釈ビューには、押されたときに詳細ビュー (PinViewController と呼ばれます) をスタックにプッシュする吹き出しボタンがあります。私の問題は、吹き出しボタンが押されたときに、そのオブジェクトからアドレスと日付を取得できるように、その注釈オブジェクトのインデックスを詳細ビュー コントローラーに渡したいことです。しかし、吹き出しボタンを押すと、それがどのアノテーションであっても、常に配列内の最初のオブジェクトのインデックスが渡されます。何が間違っているのかわかりません。誰か助けてもらえますか? ここにいくつかのコードがあります:

- (void)mapView:(MKMapView *)mapView
annotationView:(MKAnnotationView *)view
calloutAccessoryControlTapped:(UIControl *)control {

    PinViewController *pvc = [[PinViewController alloc]init];
    [[self navigationController]pushViewController:pvc animated:YES];
    NSUInteger pinIndex = [[Data singleton].annotations indexOfObject:view.annotation];
    [pvc setIdentifier:pinIndex];
} 

これは、詳細ビュー コントローラーからのものです。

- (void)viewDidLoad {
    [super viewDidLoad];

    [self.labelView setFrame:CGRectMake(10, 260, 300, 230)];
    [PinViewController roundView:self.labelView onCorner:UIRectCornerAllCorners radius:15];
    [[self view]addSubview:self.labelView];

    self.annotation = [[Data singleton].annotations objectAtIndex:self.identifier];
    self.addressLabel.text = self.annotation.address;
    self.dateLabel.text = self.annotation.subtitle;
}

注釈が配列に追加される場所は次のとおりです。

- (void)press:(UILongPressGestureRecognizer *)recognizer {
    CGPoint touchPoint = [recognizer locationInView:self.worldView];
    CLLocationCoordinate2D touchMapCoordinate = [self.worldView convertPoint:touchPoint toCoordinateFromView:self.worldView];

    self.geocoder = [[CLGeocoder alloc]init];
    CLLocation *location = [[CLLocation alloc]initWithCoordinate:touchMapCoordinate
                                                        altitude:CLLocationDistanceMax
                                              horizontalAccuracy:kCLLocationAccuracyBest
                                                verticalAccuracy:kCLLocationAccuracyBest
                                                       timestamp:[NSDate date]];
    [self.geocoder reverseGeocodeLocation:location
                   completionHandler:^(NSArray *placemarks, NSError *error) {
                       //NSLog(@"reverseGeocoder:completionHandler: called");
                       if (error) {
                           NSLog(@"Geocoder failed with error: %@", error);
                       } else {
                           CLPlacemark *place = [placemarks objectAtIndex:0];
                           self.geocodedAddress = [NSString stringWithFormat:@"%@ %@, %@ %@", [place subThoroughfare], [place thoroughfare], [place locality], [place administrativeArea]];
                           if (UIGestureRecognizerStateBegan == [recognizer state]) {
                               self.addressPin = [[MapPoint alloc]initWithAddress:self.geocodedAddress
                                                                   coordinate:touchMapCoordinate
                                                                        title:self.geocodedAddress];
                               [[Data singleton].annotations addObject:self.addressPin];
                               [self.worldView addAnnotation:self.addressPin];
                               NSLog(@"The number of pins in the annotation array is: %u",[Data singleton].annotations.count);
                           }
                       }
                   }];
}

したがって、基本的に、PinViewController に渡されるインデックスは、それがどのアノテーションであっても常に 0 です。このコードが機能しない理由がわかりません。

4

1 に答える 1

3

NSArray indexOfObjectメソッドは、各配列メンバーでisEqualを呼び出して、それらが同じであるかどうかを判別します。オブジェクトが実際に等しい場合にのみYESを返すようにしましたか?等しくない場合でも、オブジェクトがYESを返すと思われます

https://developer.apple.com/library/mac/#documentation/Cocoa/Reference/Foundation/Classes/NSArray_Class/NSArray.html

インデックス0から開始して、一致が見つかるか、配列の最後に到達するまで、配列の各要素にisEqual:メッセージが送信されます。このメソッドは、anObjectパラメーターを各isEqual:メッセージに渡します。isEqual :( NSObjectプロトコルで宣言されている)がYESを返す場合、オブジェクトは等しいと見なされます。

NSNumberのような一般的な基礎クラスはすでに実装されているため、配列メソッドisEqualですぐに使用できますindexOfObjects

NSMutableArray* arr = [[NSMutableArray alloc] init];
[arr addObject:[NSNumber numberWithInt:3]];
[arr addObject:[NSNumber numberWithInt:2]];

[arr indexOfObject:[NSNumber numberWithInt:2]]; // gives 1

ただし、などのカスタムクラスを実装した場合MapView、Objective Cはオブジェクトを比較する方法がわからないため、isEqualコンパレータを自分 で実装する必要があります。

MapView等式を決定するために呼び出される整数プロパティがあると仮定するとcow(たとえば、2つMapViewが同じcow値の場合、それらは等しい)、次のように記述します。

@interface MapView : NSObject {

}

@property (nonatomic, assign) int cow;

- (BOOL)isEqual:(id)object


@implementation MapView

@synthesize cow

- (BOOL) isEqual:(id)object
{
    MapView* otherMapview = (MapView*) object;

    return cow == otherMapview.cow;
}
于 2013-02-24T22:04:46.167 に答える