MKMapView doesn't zoom correctly while user tracking mode is MKUserTrackingModeFollowWithHeading
From apple documentation:
Setting the tracking mode to MKUserTrackingModeFollow or
MKUserTrackingModeFollowWithHeading causes the map view to center the
map on that location and begin tracking the user’s location. If the
map is zoomed out, the map view automatically zooms in on the user’s
location, effectively changing the current visible region.
If you want both to adjust the region and to track the user, I suggest you check for location updates and adjust zoom accordingly.
For example:
- (void)mapView:(MKMapView *)mapView didUpdateUserLocation:(MKUserLocation *)userLocation {
MKCoordinateRegion region = MKCoordinateRegionMakeWithDistance(userLocation.coordinate, 200.0f, 200.0f);
[self.mapView setRegion:region animated:YES];
}
EDIT
Instead of setting the region, try just setting the center,
- (void)mapView:(MKMapView *)mapView didUpdateUserLocation:(MKUserLocation *)userLocation {
[self.mapView setCenterCoordinate:userLocation.location.coordinate animated:YES];
}
and let your button action set the zoom, keeping the same center:
- (IBAction)changeRegion:(id)sender {
MKCoordinateRegion region = MKCoordinateRegionMakeWithDistance(self.mapView.centerCoordinate, 200.0f, 200.0f);
[self.mapView setRegion:region animated:YES];
}
And very important: do not set your mapView to track user. Disable tracking user because now you are tracking it yourself. I think the default is MKUserTrackingModeNone
.
MKMapView sometimes zoomz to user location sometimes zooms to middle of nowhere
I encountered this issue before. It seems that mapView is slow to load and detect user location sometimes, resulting in your code in viewDidAppear
being executed before the map view can check user's location. Thus, the spot in the ocean.
It will be better to use mapView's delegate to display user location when it's ready:
- (void)mapView:(MKMapView *)mapView didUpdateUserLocation:(MKUserLocation *)userLocation
{
if(isShowUserLocation)
{
MKCoordinateRegion region = MKCoordinateRegionMakeWithDistance(userLocation.coordinate, 600.0, 600.0);
[self.mapView setRegion:[self.mapView regionThatFits:region] animated:YES];
isShowUserLocation = NO;
}
}
Set isShowUserLocation = YES
in viewDidLoad
. This ensures the user location is shown once on entry and also selectively when you need it.
Edit 1:
@implementation MapViewController
{
BOOL isShowUserLocation;
}
-(void) viewDidLoad
{
[super viewDidLoad];
self.mapView.delegate = self;
[self.mapView setShowsUserLocation:YES];
isShowUserLocation = YES;
}
Edit 2:
Alternatively, use CLLocationManager - see this post. It allows you stop the updating. Do include CoreLocation.framework. You may need to handle some nitty-gritty issues when interacting CLLocationManager with MapView though.
Related Topics
Extract Last Word in String with Swift
How Can One Enable Keyboard Like in Imessages/Fb Messenger in Landscape Mode at iOS8
Swiftui: How to Get Continuous Updates from Slider
Xcode5 Simulator: Unknown Option Character 'X' In: -Xlinker
Type 'Nsattributedstringkey' (Aka 'Nsstring') Has No Member 'Font'
Uiapplicationlaunchoptionsremotenotificationkey Not Getting Userinfo
Add Button at the End of Collection View in Storyboard
Swift: Load Images Async in Uitableviewcell
Urlsessiondelegate Function Not Being Called
Mkmapview Doesn't Zoom Correctly While User Tracking Mode Is Mkusertrackingmodefollowwithheading
Grouping Coredata by Date() in Swiftui List as Sections
App Is Not Showing in the Share Menu of Shared Options in Shared Extension in iOS8
Xcode 7 Beta 6, Dyld _Nsarray0_ Crash
Auto-Implement Swift Protocol Methods in Xcode
Parsing JSON Using the New Swift 3 and Alamofire
How to Use Avcapturephotooutput to Capture Photo Swift + Xcode