MapBox добавляет интерактивную аннотацию/представление в местоположении iOS

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

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

Вопрос Как создать аннотацию с кнопкой/представлением в MapBox, как мне подойти.

Любая помощь приветствуется.

Спасибо.

Изменить:

Чтобы быть более точным, я хочу что-то вроде изображения ниже введите описание изображения здесьдля аннотации..


person iphonic    schedule 01.10.2013    source источник


Ответы (4)


Наконец-то я могу заставить это работать. Я создал класс Subclassed RMMarker в проекте MapBox и добавляю все компоненты как CALayer, добавляя компоненты в UIView, а затем добавляя UIView.layer не работает. Вы должны добавить подслои в слой UIView.

Затем я создал собственные делегаты для обработки событий касания.

Убедитесь, что вы используете MapBox из здесь и добавьте MyMarker в проект MapBox в качестве компонента.

Я добавляю свой код здесь

Мой маркер.h

#import "RMMarker.h"

@interface MyMarker : RMMarker 
@end 

MyMarker.m

@implementation MyMarker 
-(id)init{ 

    self=[super init]; 

    if(self){ 


       UIView *subLayer=[[UIView alloc] initWithFrame:CGRectMake(0, 0, 126, 91)];



       UIView *smallView=[[UIView alloc] initWithFrame:CGRectMake(36.0, 0, 88, 91)];

       //smallView.contents=(id)image;

       [subLayer.layer addSublayer:smallView.layer]; 

       subLayer.backgroundColor=[UIColor blueColor]; 

       subLayer.layer.name=@"Annotation"; 

       [self addSublayer:smallView.layer]; 


        float y=11.0; 
        float x=12.0; 

        for(int i=0;i<4;i++){ 
           CGPoint pt=CGPointMake(x, y); 
           UIView *handle=[self createHandle:@"Handle" fromPos:pt]; 
           y=y+14.0; 
           handle.layer.name=[NSString stringWithFormat:@"Handle at %@",NSStringFromCGPoint(pt)]; 
           [self addSublayer:handle.layer]; 
      } 
   } 

   return self; 
}

-(UIView *)createHandle:(NSString *)handle fromPos:(CGPoint)pos{

    UIView *view=[[UIView alloc] initWithFrame:CGRectMake(pos.x, pos.y, 60.0, 5.0)]; 

    view.backgroundColor=[UIColor brownColor]; 


    return view; 


} 
@end

RMMapViewDelegate.h

- (void)tapOnMarker:(MyMarker *)marker at:(CGPoint )pt;

RMMapView.m

Добавлено BOOL _delegateHasMyMarkerDelegate;

Настройка свойств метода делегата

- (void)setDelegate:(id <RMMapViewDelegate>)aDelegate{ 
     _delegateHasMyMarkerDelegate=[_delegate respondsToSelector:@selector(tapOnMarker:at:)]; 
}

- (void)tapOnMarker:(MyMarker *)marker at:(CGPoint)aPoint 
{ 
    if (_delegateHasMyMarkerDelegate) 
   { 
        [_delegate tapOnMarker:marker at:aPoint]; 
   } 

}

- (void)handleSingleTap:(UIGestureRecognizer *)recognizer{ 
    //Default initializers

     CALayer *superlayer = [hit superlayer];

    // See if tap was on an annotation layer or marker label and send delegate protocol method 
   //Added conditions for MyMarker touch events 
    if ([superlayer superlayer] != nil && [[superlayer superlayer] isKindOfClass:[MyMarker class]]){ 

         [self tapOnMarker:((MyMarker *)[superlayer superlayer]) at:[recognizer locationInView:self]]; 

}else if ([[superlayer superlayer] superlayer] != nil && [[[superlayer superlayer] superlayer] isKindOfClass:[MyMarker class]]){ 

        [self tapOnMarker:((MyMarker *)[[superlayer superlayer] superlayer]) at:[recognizer locationInView:self]]; 

}else if (superlayer != nil && [superlayer isKindOfClass:[MyMarker class]]){ 

        [self tapOnMarker:((MyMarker *)superlayer) at:[recognizer locationInView:self]]; 

   }

}

Реализация

-(RMMapLayer *)mapView:(RMMapView *)mapView layerForAnnotation:(RMAnnotation *)annotation{

     if(annotation.isUserLocationAnnotation) 
         return nil;

    MyMarker *marker=[[MyMarker alloc] init]; 
    [marker setFrame:CGRectMake(0, 0, 126, 91)]; 


     return marker;

}

#pragma mark MyMarker Delegate

-(void)tapOnMarker:(MyMarker *)marker at:(CGPoint)pt{ 

    for (CALayer *layer in marker.sublayers) { 
        CGPoint convertedPt=[[marker superlayer] convertPoint:pt toLayer:layer]; 
        if([layer containsPoint:convertedPt]){ 
             NSLog(@"%@ selected",layer.name); 
        } 

    }

}

Надеюсь, это поможет кому-то, кто хочет создать маркер/аннотацию и выполнить над ним несколько действий.

person iphonic    schedule 11.11.2013
comment
Я смог реализовать аналогичный подход с awesomeMenu, но обязательно попробую. Спасибо. - person Felix; 04.04.2014

Почему бы просто не использовать - (void) singleTapOnMap:(RMMapView *)map at:(CGPoint)point делегата? Я не вижу, чтобы вы использовали какие-либо состояния кнопок, поэтому мне кажется, что самый простой способ:

func singleTapOnMap(map: RMMapView!, at point: CGPoint) {
        let layer = someObject.layer
        let frameOnScreen = layer.superlayer.convertRect(layer.frame, toLayer: map.layer)

        if CGRectContainsPoint(frameOnScreen, point) {
            NSLog("hit")
        }
    }
person Mike    schedule 02.04.2015
comment
Хотя он довольно старый, но вы не правильно прочитали требование, я думаю, использование вышеуказанной функции позволит выбрать всю аннотацию, мое требование состояло в том, чтобы разработать одну аннотацию с несколькими действиями в ней, я буду рад, что вы добавите больше правильный ответ на него. Может быть, MapBox со временем стало лучше, я давно за этим не слежу. Я внес свое решение в MapBox, и они его тоже приняли. - person iphonic; 02.04.2015

Вы также можете использовать:

func mapView(mapView: RMMapView!, didSelectAnnotation annotation: RMAnnotation!)

делегировать метод и делать то, что вы хотели сделать в действии нажатия кнопки.

person berilcetin    schedule 15.04.2015
comment
НЕТ, на didSelectAnnotation кнопки появляются. Кнопки добавляются в аннотацию. - person iphonic; 16.04.2015
comment
Ах, извините, я неправильно понял ваш вопрос. Но вместо того, чтобы добавлять кнопки в аннотацию, не могли бы вы просто добавить их в суперпредставление и расположить их в соответствии с положением аннотации? Я предполагаю, что эти кнопки будут отображаться для каждой аннотации. Таким образом, вы могли бы избежать слоев и прочего, ((MyMarker )[[superlayer superlayer] superlayer] не очень хорошо) и просто реализовать действия кнопок в вашем контроллере представления. И вы можете получить точку аннотации с помощью: self.mapView.coordinateToPixel(annotation.coordinate) - person berilcetin; 16.04.2015
comment
НЕТ, это тоже невозможно, поскольку MapBox использует CALayer для своих реализаций, а не UIView, иначе это было бы сделано так, как вы сказали. - person iphonic; 16.04.2015
comment
Нет, я имею в виду, что вы могли бы просто добавить кнопки в супервизор карты. Что определенно должно быть UIView - person berilcetin; 16.04.2015
comment
Да, я понял, вы говорите добавить прямо на карту, это может создать проблемы с макетом при увеличении / уменьшении, и я не уверен, хотя это очень старая проблема. до этого решения, конечно, его можно оптимизировать. - person iphonic; 16.04.2015

Взгляните на этот пример в документации MapBox: http://www.mapbox.com/mapbox-ios-sdk/examples/callout-accessory-view/ Работает очень похоже на MapKit.

person incanus    schedule 02.10.2013
comment
Спасибо @incanus, но приведенная выше ссылка не решает мою задачу. - person iphonic; 02.10.2013