Подтвердить что ты не робот

Настроить выноску MKAnnotationView

Я хочу создать настраиваемую выноску MKAnnotationView, как показано на этом изображении. Я тестировал несколько решений, но они позволяют настраивать только левые/правые изображения и заголовок/субтитры. Может ли кто-нибудь, пожалуйста, дать мне какой-то исходный код или ссылку для учебника?

В настоящее время я не знаю. Пожалуйста, помогите.

enter image description here

4b9b3361

Ответ 1

Я понимаю, что вам нужен булавка с настраиваемой выноской.

Мы не можем создать настраиваемую выноску, но мы можем создать аннотацию с полностью настроенным представлением. Таким образом, трюк заключается в том, чтобы добавить вторую аннотацию, когда первый выбран, и сделать второй аннотационный вид похожим на пузырь выноски.

Это решение опубликовано пользователями djibouti33 и jacob-jennings в ответе: MKAnnotationView - заблокировать пользовательский аннотационный просмотр для привязки к обновлениям местоположения, который, в свою очередь, основан на блоге от решений Asynchrony. Для объяснения целей, вот некоторые UML из раздвоенного проекта: Annotation with custom XIB

Это большой взлом, но также и самый чистый способ, с помощью которого я реализовал пользовательские аннотации.

Начните с класса NSObject "Content", который имеет координату, класс используемого вида выноски (в UML есть AnnotationView, но вы можете создать больше и установить их здесь) и словарь случайных значений с помощью title, photo url и т.д. Используйте этот класс для инициализации объекта "Аннотации" MKAnnotation.

#import <MapKit/MapKit.h>
@interface Content : NSObject
@property (nonatomic,assign) CLLocationCoordinate2D coordinate;
// ...

@interface Annotation : NSObject <MKAnnotation, AnnotationProtocol>
-(id) initWithContent:(Content*)content;
// ...

Annotation реализует AnnotationProtocol, чтобы объявить, что хочет обработать создание своего собственного MKAnnotationView. То есть ваш MKMapViewDelegate должен иметь такой код:

- (MKAnnotationView *)mapView:(MKMapView *)aMapView viewForAnnotation:(id<MKAnnotation>)annotation 
{
    // if this is a custom annotation, delegate the implementation of the view
    if ([annotation conformsToProtocol:@protocol(AnnotationProtocol)]) {
        return [((NSObject<AnnotationProtocol>*)annotation) annotationViewInMap:mapView];
    } else {
        // else, return a standard annotation view
        // ...
    }
} 

Возвращаемое представление будет иметь тип AnnotationView, который реализует AnnotationViewProtocol, чтобы объявить, что он хочет обрабатывать выбор/отмена выбора. Поэтому в вашем контроллере просмотра карты методы mapView: didSelectAnnotationView: и mapView: didDeselectAnnotationView: должен делегировать аналогично тому, что мы видели раньше.

При выборе аннотации добавляется вторая аннотация (CalloutAnnotation), которая следует за тем же поведением, но на этот раз возвращенный вид (CalloutView) инициализируется из XIB и содержит код Core Graphics (в BaseCalloutView) для анимации и скопируйте выноску.

Инициализатор класса CalloutView:

- (id)initWithAnnotation:(CalloutAnnotation*)annotation
{
    NSString *identifier = NSStringFromClass([self class]);
    self = [super initWithAnnotation:annotation reuseIdentifier:identifier];
    if (self!=nil){
        [[NSBundle mainBundle] loadNibNamed:identifier owner:self options:nil];
        // prevent the tap and double tap from reaching views underneath
        UITapGestureRecognizer *tapGestureRecognizer = ...
    }
    return self;
}

Чтобы иметь возможность нажать другой контроллер вида из представления выноска, я использовал уведомления.

Ответ SO, на который я связан сверху, содержит два полных проекта, реализующих этот код (имена классов могут отличаться). У меня есть другой проект с использованием UML выше в https://github.com/j4n0/callout.

Ответ 2

Я добавил пользовательский UIButton в MKAnnotationView. И при нажатии этой кнопки я показал popOver с помощью rootViewController с видом, подобным тому, что вы показали выше.