Disable compass on MKMapView

自古美人都是妖i 提交于 2019-12-03 05:30:19
Mark Amery

You can disable the compass easily on OSX 10.9 / iOS 9 and later with the showsCompass property:

yourMapView.showsCompass = NO;

On iOS 8 or earlier, your choices are:

  1. Suck it up and live with it.

  2. Use a hack, like:

  3. If you're not rotating the map programatically and it hasn't already been rotated, disable rotation entirely, using

    mapView.rotateEnabled = NO;
    

    The compass only shows up when the map is rotated, so by doing this you ensure that the compass is never triggered.

It's not clear to me why Apple waited so long to allow hiding the compass on iOS, and none of the options above are ideal. Pick whichever you think is the least bad in your case.

I found a solution to your problem, using Mark Amery's idea about traversing the MKMapView instance subviews to find the compass, along with the use of gesture recognition to trigger the removal event.

To find the compass I printed out the description of the views and found that one of the views was an instance of MKCompassView, this was obviously the compass.

I have come up with the following code that should work for you. It checks for a rotation gesture, and then removes the view in method triggered by the gesture event.

I have tested this method and it works well for me:

- (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];
            }
        }
    }
}
AlexWien

Create a wrapper UIView with the frame you want for your map and clipsToBounds set to YES (or equivalently, Clip Subviews set in Interface Builder). Then put your MKMapView inside that wrapper view, with the y co-ordinate of the map's frame set to, for example, -80, and the height of the map set such that its vertical center is aligned with its parent.

Then the compass will be displayed but you cannot see it, because it is above the top of its parent view - problem solved.

Here is solution for Swift 4:

mapView.compassView.isHidden = true

Here swift code:

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()
            }
        }
    }
}

You can hide the compass on MKMapView while rotating the map by adding below line in viewDidLoad method in all iOS:

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

Completely hides the compass and does not rotate the map

mapView.allowsRotating = false

Swift 4, Mapbox-iOS-SDK (4.9.0)

As I understand what you want is to forbid showing user's current location. You should use @property(nonatomic) BOOL showsUserLocation. Docs on this

Assume that @property(nonatomic) MKUserTrackingMode userTrackingMode can't enable or disable tracking, it's just changes the mode between not following, following and following with rotating.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!