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,您可以从中确定相等性(例如:如果两个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 回答