【问题标题】:MapBox add interactive annotation/view at location iOSMapBox 在 iOS 位置添加交互式注释/视图
【发布时间】:2013-10-01 13:53:00
【问题描述】:

我正在尝试实现 MapBox 地图,使用它的特殊原因,它是高度可定制的,我需要创建一种具有所有不同颜色的不同类型的地图,我做得很好。

我想在应该从内部交互的地图上添加注释的问题,通常只需点击注释即可交互,它可以工作,我需要注释中的 UIButton 并单击应该执行的按钮操作。

问题 如何在 MapBox 中使用按钮/视图创建注释,我应该如何处理。

感谢任何帮助。

谢谢。

编辑:

更准确地说,我想要像下面 的图像作为注释..

【问题讨论】:

    标签: ios objective-c map annotations mapbox


    【解决方案1】:

    我终于能够完成这项工作。我在 MapBox 项目中创建了一个 Subclassed RMMarker 类,我将所有组件添加为 CALayer,在 UIView 添加组件然后添加 UIView.layer 不起作用。您必须在 UIView 层中添加子层。

    然后我创建了自定义委托来处理触摸事件。

    确保您使用来自 here 的 MapBox,并将 MyMarker 作为组件添加到 MapBox 项目中。

    我在这里添加我的代码

    MyMarker.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); 
            } 
    
        }
    
    }
    

    希望它对想要创建标记/注释并希望对其进行多项操作的人有所帮助。

    【讨论】:

    • 我能够使用 awesomeMenu 实现类似的方法,但我肯定会尝试。谢谢。
    【解决方案2】:

    为什么不简单地使用- (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")
            }
        }
    

    【讨论】:

    • 虽然很老了,但我猜你没有正确阅读要求,使用上述功能将允许选择整个注释,我的要求是设计一个包含多个操作的单个注释,我会很高兴你添加更多正确的答案。可能是MapBox 随着时间的推移而有所改善,我不会长期关注它。我已将我的解决方案贡献给 MapBox,他们也接受了。
    【解决方案3】:

    你也可以使用:

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

    委托方法,并在按钮点击操作中执行您想要执行的操作。

    【讨论】:

    • 否,在 didSelectAnnotation 上,按钮出现。按钮添加在注释中。
    • 对不起,我误解了你的问题。但是不是在注解中添加按钮,您不能将它们添加到超级视图并根据注解位置进行布局吗?我假设这些按钮会出现在每个注释中。这样你就可以避免层和东西,((MyMarker)[[superlayer superlayer] superlayer] 不好),只需在视图控制器中实现按钮操作。您可以通过以下方式获得注释点:self.mapView.coordinateToPixel(annotation.coordinate)
    • 不,这也是不可能的,因为 MapBox 使用 CALayer 来实现其实现,而不是 UIView,否则它会像你说的那样完成。
    • 不,我的意思是您可以将按钮添加到地图框的超级视图中。哪个是明确的必须是 UIView
    • 是的,我明白了,您是说直接添加到地图中,如果放大/缩小可能会产生布局问题,我不确定,尽管这是一个非常古老的问题,尝试了很多时间不记得了,当然想出了这个方案,可以优化一下。
    【解决方案4】:

    查看 MapBox 文档中的此示例:http://www.mapbox.com/mapbox-ios-sdk/examples/callout-accessory-view/ 这与 MapKit 非常相似。

    【讨论】:

    • 感谢@incanus,但上面的链接不能解决我的目的。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-07-23
    • 2017-02-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多