Хранить данные в MKAnnotation?

Итак, я довольно новичок в Xcode и Objective-C. У меня есть несколько объектов ArtPiece с различными атрибутами, хранящимися в массиве. Затем я добавляю их как MKnnotations в mapview. То, что мне нужно сделать, это отправить ссылку на позицию массива, из которой они пришли, щелкнув. Я считаю, что MKAnnotes имеет только название, изображение и местоположение членов данных, поэтому, когда я делаю MKAnnotation из объектов, аннотация не сохраняет никаких других атрибутов. Итак, мой вопрос заключается в том, как мне удастся сохранить ссылку на позицию массива объекта, с которой была создана аннотация, чтобы я мог отправить ее другим методам, чтобы они могли получить дополнительную информацию об объекте из массива для подробного описания просмотры и т.д. Есть ли способ сохранить в аннотации одно значение int? Я не думаю, что есть какие-то другие идеи?

Вот мой ArtPiece.h:

#import <Foundation/Foundation.h>
#import <MapKit/MapKit.h>
@interface ArtPiece : NSObject <MKAnnotation>{

    NSString *title;
    NSString *artist;
    NSString *series;
    NSString *description;
    NSString *location;
    NSString *area;
    NSNumber *latitude;
    NSNumber *longitude;
    UIImage *image;
}

@property (nonatomic, retain) NSString *title;
@property (nonatomic, retain) NSString *artist;
@property (nonatomic, retain) NSString *series;
@property (nonatomic, retain) NSString *description;
@property (nonatomic, retain) NSString *location;
@property (nonatomic, retain) NSString *area;
@property (nonatomic, retain) NSNumber *latitude;
@property (nonatomic, retain) NSNumber *longitude;
@property (nonatomic, retain) UIImage *image;


@end

и вот .m:

#import "ArtPiece.h"
#import "FindArtController.h"
#import "ArtPiece.h"
#import <MapKit/MapKit.h>

@implementation ArtPiece

- (NSString *)description{
    return [NSString stringWithFormat:@"title: %@",title];
}

@synthesize title, artist, series, description, latitude, longitude, location, area, image;

- (CLLocationCoordinate2D)coordinate
{
    CLLocationCoordinate2D theCoordinate;
    theCoordinate.latitude = [self.latitude doubleValue];
    theCoordinate.longitude = [self.longitude doubleValue];
    return theCoordinate;
}




@end

Затем я продолжаю создавать объекты этого класса, устанавливать их значения и добавлять их в массив в AppDelegate. Затем в другом классе я использую:

[self.mapView addAnnotations:mainDelegate.mapAnnotations];

чтобы добавить аннотации к карте. Однако, когда я пытаюсь установить атрибут "artist" в методе viewforannotation, я получаю "запрос для участника-исполнителя в чем-то, что не является структурой или объединением".

Очевидно, что я должен делать это подклассифицирование неправильно, но что я могу изменить?

Вот метод viewforannotation, который у меня есть сейчас. Строка test.artist... не работает.

- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>)annotation{
    MKAnnotationView *test=[[MKAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:@"reuse"];
    test.image = [UIImage imageNamed:@"pao_pin.png"];
    [test setCanShowCallout:YES];
    [test setUserInteractionEnabled:YES];
    test.rightCalloutAccessoryView =
    [UIButton buttonWithType:UIButtonTypeDetailDisclosure];
    test.artist = annotation.artist;
    return test;    
}

Итак, если я: annotation = (ArtPiece *)annotation Короче говоря, моя цель состоит в том, чтобы иметь возможность хранить ссылку на позицию массива объекта в этой аннотации, из которой я могу отправить это другим методам, которые могут получить доступ к этому объекту для подробных представлений и т.д.

Ответы

Ответ 1

В методе viewForAnnotation вы можете получить доступ к вашим свойствам ArtPiece, но чтобы избежать ошибок и предупреждений компилятора, вам нужно сначала применить параметр annotation к своему пользовательскому классу. Параметр annotation в этом методе определяется как id<MKAnnotation>, поэтому компилятор не будет знать о свойствах, специфичных для ArtPiece (пока вы не скажете, что это экземпляр ArtPiece).

Вам понадобится что-то вроде этого:

ArtPiece *artPiece = (ArtPiece *)annotation;
NSString *artist = artPiece.artist;

Edit:
Когда нажата кнопка вызова аннотационного вида, представление карты вызывает метод делегата calloutAccessoryControlTapped. Этот метод получает MKAnnotationView в параметре view. Сам объект аннотации находится в свойстве annotation параметра view. Вы можете применить этот объект к своему пользовательскому классу для доступа к вашим свойствам ArtPiece:

- (void)mapView:(MKMapView *)mapView annotationView:(MKAnnotationView *)view calloutAccessoryControlTapped:(UIControl *)control
{
    ArtPiece *artPiece = (ArtPiece *)view.annotation;
    NSString *artist = artPiece.artist;
}

Другими словами, обработчик кнопки вызова не нуждается в доступе к исходному массиву. Он получает ссылку на фактический объект ArtPiece.

Ответ 2

Создайте подкласс MKAnnotation, и вы можете добавить любые дополнительные данные, которые вам нужны.

Ответ 3

Кажется, здесь какая-то путаница.

MKAnnotation - это протокол, а не класс, поэтому вы не подклассифицируете его, вы его реализуете. Любой объект может быть MKAnnotation, если он реализует протокол MKAnnotation (координата, название, субтитры), и этот объект может иметь любое другое свойство, которое вам нравится, если вы его создаете. Вы сделали это правильно выше.

Зачастую вам нужно будет отнести этот <MKAnnotation> к своему пользовательскому классу, как сказала Анна Каренина, чтобы сообщить компилятору, какой тип объекта он имеет.

MKAnnotationView С другой стороны, это класс (и подкласс UIView), и если вы хотите создать свой собственный, вы можете подклассифицировать его. Затем, когда он создается и используется картой, он содержит ссылку на свой связанный MKAnnotation, поэтому в вашем пользовательском MKAnnotationView вы можете:

self.artistLabel.text = [(ArtPiece *)self.annotation artist];

Ответ 4

Каждая аннотация содержит уникальный идентификатор. Используйте NSMutableDictionary и используйте уникальный идентификатор аннотации в качестве ключа для любых объектов, которые вы хотите. позже вы можете получить доступ, когда вы вызываете это:

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