在 MKMapView 上禁用指南针

Posted

技术标签:

【中文标题】在 MKMapView 上禁用指南针【英文标题】:Disable compass on MKMapView 【发布时间】:2013-10-12 07:41:21 【问题描述】:

我在我的应用程序中使用 MapView 来显示一些注释。在 ios 7 中,指南针随机出现在地图上。我无法重现该错误,因为它随机出现,但我想禁用它。 任何想法如何禁用它?

更新:我发现不是随机出现,而是在特定手势上出现。当您使用 2 根手指并向右滑动另一根手指时。

【问题讨论】:

那个手势也被称为“旋转” 【参考方案1】:

您可以在 OSX 10.9 / iOS 9 及更高版本上使用showsCompass 属性轻松禁用指南针。

目标-C:

mapView.showsCompass = NO;

斯威夫特:

mapView.showsCompass = false

以这种方式隐藏指南针不会阻止自定义 MKCompassButton 正常运行和显示。

在 iOS 8 或更早版本上,您的选择是:

    接受它并接受它。

    使用 hack,例如:

    position the map to hide the compass offscreen(感谢 Alex Wien),或者

    walk the view hierarchy of the map to find the view representing the compass and remove it(感谢 David Topolansky)。

    如果您没有以编程方式旋转地图并且它还没有被旋转,请完全禁用旋转,使用

     mapView.rotateEnabled = NO;
    

指南针仅在地图旋转时显示,因此这样做可以确保指南针永远不会被触发。

我不清楚为什么 Apple 等了这么久才允许在 iOS 上隐藏指南针,而且上述选项都不理想。选择你认为对你的情况最不利的那个。

【讨论】:

【参考方案2】:

我找到了解决您的问题的方法,使用 Mark Amery 关于遍历 MKMapView 实例子视图来查找指南针的想法,以及使用手势识别来触发移除事件。

为了找到指南针,我打印了视图的描述,发现其中一个视图是MKCompassView 的实例,这显然是指南针。

我想出了以下代码,应该适合你。它检查旋转手势,然后在由手势事件触发的方法中移除视图。

我已经测试过这个方法,它对我很有效:

- (void)viewDidLoad

    [super viewDidLoad];

    UIRotationGestureRecognizer *rotateGesture = [[UIRotationGestureRecognizer alloc] initWithTarget:self action:@selector(rotate:)];

    [self.mapView addGestureRecognizer:rotateGesture];


-(void)rotate:(UIRotationGestureRecognizer *)gesture

    if ([gesture state] == UIGestureRecognizerStateBegan || [gesture state] == UIGestureRecognizerStateChanged) 
        // Gets array of subviews from the map view (MKMapView)
        NSArray *mapSubViews = self.mapView.subviews;

        for (UIView *view in mapSubViews) 
            // Checks if the view is of class MKCompassView
            if ([view isKindOfClass:NSClassFromString(@"MKCompassView")]) 
                // Removes view from mapView
                [view removeFromSuperview];
            
        
    

【讨论】:

这算作“使用私有 API”并在 Apple 扫描您的二进制文件期间被标记吗? 很好 - 我很惊讶这个 hack 实现和理解如此简单。我现在无法使用 Mac,所以我无法对此进行测试,但会相信你的话,它可以工作。我已将指向您答案的链接编辑到我的。 旋转手势对我不起作用,但我实现了视图控制器的 - (void)viewDidLayoutSubviews 方法并将代码移到那里,现在它可以工作了。【参考方案3】:

创建一个包装器UIView,并使用您想要的地图框架并将clipsToBounds 设置为YES(或等效地,在界面生成器中设置剪辑子视图)。然后将您的MKMapView 放入该包装视图中,地图框架的y 坐标设置为例如-80,地图的高度设置为使其垂直中心与其父级对齐。

然后指南针将显示,但您看不到它,因为它位于其父视图的顶部 - 问题已解决。

【讨论】:

【参考方案4】:

这是 Swift 4 的解决方案:

mapView.compassView.isHidden = true

【讨论】:

【参考方案5】:

这里是swift代码:

let mapRotateGesture = UIRotationGestureRecognizer(target: self, action: "didRotateMap:")
mapRotateGesture.delegate = self
self.map.addGestureRecognizer(mapRotateGesture)

func didRotateMap(gesture: UIGestureRecognizer) 
    // Removeing compass
    if (gesture.state == .Began || gesture.state == .Changed) 
        for view in map.subviews as! [UIView] 
            if view.isKindOfClass(NSClassFromString("MKCompassView")) 
                view.removeFromSuperview()
            
        
    

【讨论】:

【参考方案6】:

您可以在旋转地图时隐藏 MKMapView 上的指南针,方法是在所有 iOS 的 viewDidLoad 方法中添加以下行:

[self.mapView setLayoutMargins:UIEdgeInsetsMake(-50, 0, -50, 0)];

【讨论】:

【参考方案7】:

完全隐藏指南针,不旋转地图

mapView.allowsRotating = false

Swift 4,Mapbox-iOS-SDK (4.9.0)

【讨论】:

【参考方案8】:

据我了解,您想要的是禁止显示用户的当前位置。 您应该使用 @property(nonatomic) BOOL 显示用户位置。 Docs on this

假设@property(nonatomic) MKUserTrackingMode userTrackingMode 无法启用或禁用跟踪,它只是在不跟随、跟随和旋转跟随之间更改模式。

【讨论】:

不,我需要显示用户位置。我不需要的是指南针。 我发现不是随机出现,而是出现在特定的手势上。当您使用两根手指并且一根手指向右滑动,另一根手指向左滑动时。 好吧,现在我明白你想要什么了。文档向我们展示使用 rotateEnabled 禁用地图旋转的唯一方法。这将阻止启用旋转手势。 如果你需要旋转你的地图,你可以添加 UIRotationGestureRecognizer 到地图的视图添加旋转它你想要的方式使用 [mapView setTransform:CGAffineTransformMakeRotation(rotation)];和注释。 @VladislavMazur 有什么难理解的?他想在需要时禁用指南针,并保留旋转功能。

以上是关于在 MKMapView 上禁用指南针的主要内容,如果未能解决你的问题,请参考以下文章

禁用指南针/scss 源地图

MKMapView 不显示当前位置

仅在点击 MKUserTrackingBarButtonItem 时提示位置授权

Unity3D 官方移动游戏优化指南6.项目配置

有选择地禁用第三方库的C ++核心指南检查器

Windows服务器安全配置指南