I need help with showing the user's location on my MapView. I have done everything I could possibly find online, but it still does not work.
I have a CLLocationManager in my AppDelegate that calls the locationUpdate in my viewController.
The (void)locationUpdate:(CLLocation *)location method gets called every time and the location coordinates is correct when logged with the NSLog(). Still, there is no "Blue Dot" on my iPhone's screen. The region is not set as well.
Please take a look and tell me if I am missing anything.
This is my header file:
//My .h file
#import <UIKit/UIKit.h>
#import <MapKit/MapKit.h>
#import <MapKit/MKAnnotation.h>
#import <MapKit/MKReverseGeocoder.h>
#interface FirstViewController : UIViewController <MKMapViewDelegate>
{
MKMapView *mapView;
}
-(void)locationUpdate:(CLLocation *)location;
-(void)locationError:(NSError *)error;
#end
This is my part of my implementation file:
//My .m file
#import "FirstViewController.h"
#implementation FirstViewController
- (void)viewDidLoad
{
mapView = [[MKMapView alloc] initWithFrame:self.view.bounds];
mapView.showsUserLocation = YES;
mapView.mapType = MKMapTypeStandard;
mapView.delegate = self;
CLLocationCoordinate2D location;
MKCoordinateRegion region;// = {{0.0,0.0},{0.0,0.0}};
location.latitude = -33.8771;
location.longitude = 18.6155;
MKCoordinateSpan span;
span.latitudeDelta = 0.01;
span.longitudeDelta = 0.01;
region.span = span;
region.center = location;
[mapView setRegion:region animated:TRUE];
[mapView regionThatFits:region];
[super viewDidLoad];
}
-(void)locationUpdate:(CLLocation *)location
{
CLLocationCoordinate2D loc = [location coordinate];
[mapView setCenterCoordinate:loc];
if([mapView showsUserLocation] == NO)
[mapView setShowsUserLocation:YES];
NSLog(#"User Loc: %f, %f", mapView.userLocation.location.coordinate.latitude,
mapView.userLocation.location.coordinate.longitude);
NSLog(#"In MapView: %#",[location description]);
}
#end
Thank you for your time!
It is much appreciated!
Your Map kit in Interface Builder needs to have the (Find User Location) checked!!
Related
I have used map in my view controller but when the maps loads it shows me view of the whole country. I want to show my current location view when maps loads, for that I have used didUpdateUserLocation method and set delegate for it.
My code is this:
-(void)mapView:(MKMapView *)mapView didUpdateUserLocation:(MKUserLocation *)userLocation{
[self.mapView setRegion:MKCoordinateRegionMake(_userLocation.coordinate, MKCoordinateSpanMake(0.1f, 0.1f)) animated:YES];
}
Now when my map loads it animate and zoom but in wrong location. It is taking me to any location in sea when map loads , but my current location is different.
I have also tested it in real device but it does not show my location.
The maps looks like that when loads:
ViewController class code:
#property BOOL updateUserLocation;
#property(strong,nonatomic) CLLocation *userLocation;
#property (nonatomic, retain) MKPolyline *routeLine;
#property (nonatomic, retain) MKPolylineView *routeLineView;
#property (nonatomic,retain) NSString *latitude;
#property (nonatomic,retain) NSString *longitude;
- (void)viewDidLoad {
[super viewDidLoad];
[[self navigationController] setNavigationBarHidden:YES animated:YES];
_AlertView.hidden=YES;
_distanceView.hidden=YES;
self.mapView.zoomEnabled=YES;
locationManager = [[CLLocationManager alloc]init];
locationManager.delegate = self;
[locationManager startUpdatingLocation];
[self.mapView setShowsUserLocation:YES];
[self.mapView setDelegate:self];
}
-(void)mapView:(MKMapView *)mapView didUpdateUserLocation:(MKUserLocation *)userLocation{
[self.mapView setRegion:MKCoordinateRegionMake(_userLocation.coordinate, MKCoordinateSpanMake(0.1f, 0.1f)) animated:YES];
}
Add these lines in the viewDidLoad:
self.mapView.showsUserLocation = YES;
if you want to center the map to the user location add this:
[self.mapView setCenterCoordinate:mapView.userLocation.location.coordinate animated:YES];
EDIT:
ViewController example:
#import "ViewController.h"
#import <MapKit/MapKit.h>
#import <CoreLocation/CoreLocation.h>
#interface ViewController () <CLLocationManagerDelegate>
#property (weak, nonatomic) IBOutlet MKMapView *mapView;
#property (nonatomic, strong) CLLocationManager *locationManager;
#property (nonatomic, strong) CLLocation *location;
#end
#implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
[[self mapView] setShowsUserLocation:YES];
self.locationManager = [[CLLocationManager alloc] init];
// we have to setup the location manager with permission in later iOS versions
if ([[self locationManager] respondsToSelector:#selector(requestWhenInUseAuthorization)]) {
[[self locationManager] requestWhenInUseAuthorization];
}
[[self locationManager] setDelegate:self];
[[self locationManager] setDesiredAccuracy:kCLLocationAccuracyBest];
[[self locationManager] startUpdatingLocation];
}
-(void) locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations {
// Stop updating location, when you want to restart update use [[self locationManager] startUpdatingLocation];
[manager stopUpdatingLocation];
self.location = locations.lastObject;
// zoom the map into the users current location
MKCoordinateRegion viewRegion = MKCoordinateRegionMakeWithDistance
(self.location.coordinate, 2, 2);
[[self mapView] setRegion:viewRegion animated:YES];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#end
I've only added the IBOutlet on the storyboard and the NSLocationWhenInUseUsageDescription key in the plist.
If you change the location on the simulator you can see the maps change location.
If you want I can upload the complete example project.
NEW EDIT:
There is an error in you code!
When you use [self.mapView setRegion:MKCoordinateRegionMake(_userLocation.coordinate, MKCoordinateSpanMake(0.1f, 0.1f)) animated:YES], you use _userLocation that is your CLLocation variable! You must use userLocation that is the value that you receive from the method.
I recommend you to change the CCLocation variable name and use the userLocation name only for the variable used in the didUpdateUserLocation method.
You can call this method and zoom on map
CLLocationCoordinate2D zoomLocation;
zoomLocation.latitude = ; // your latitude value
zoomLocation.longitude= // your longitude value
MKCoordinateRegion region;
MKCoordinateSpan span;
span.latitudeDelta=0.18; // change as per your zoom level
span.longitudeDelta=0.18;
region.span=span;
region.center= zoomLocation;
[mapview setRegion:region animated:TRUE];
[mapview regionThatFits:region];
Use didUpdateToLocation instead of didUpdateUserLocation.
- (void)locationManager:(CLLocationManager *)manager
didUpdateToLocation:(CLLocation *)newLocation
fromLocation:(CLLocation *)oldLocation
{
[self.locationManager stopUpdatingLocation];
MKCoordinateRegion region;
region.span.latitudeDelta = 0.005;
region.span.longitudeDelta = 0.005;
region.center.latitude = newLocation.coordinate.latitude;
region.center.longitude = newLocation.coordinate.longitude;
[self.mapView setRegion:region animated:YES];
}
See also my library.
https://github.com/koogawa/KGWLocationPicker/blob/master/KGWLocationPicker/KGWLocationPickerViewController.m
I'm trying to get my current location to zoom in automatic in mkmapview, but i can't get it to work.
hereĀ“s a bit of code, that i want is to zoom automatic like in Runkeeper.
**the h-file**
#import <UIKit/UIKit.h>
#import <MapKit/MapKit.h>
#import <CoreLocation/CoreLocation.h>
#interface WalkingTableViewController: UIViewController <MKMapViewDelegate>
#property ( strong, nonatomic) MKMapView *mapView;
#end
**the m-file**
#import "WalkingTableViewController.h"
#interface WalkingTableViewController ()
#end
#implementation WalkingTableViewController
- (void)viewDidLoad
{
[super viewDidLoad];
self.mapView.showsUserLocation=YES;
self.mapView.delegate = self;
[self.mapView setUserTrackingMode:MKUserTrackingModeFollow animated:YES];
// zoom in on users location (?)
}
#end
You need to set the region, something like:
MKCoordinateRegion region;
region = MKCoordinateRegionMakeWithDistance(_mapView.userLocation.coordinate,10000,10000);
[_mapView setRegion:region animated:YES];
The 10000 is the distance from your center point you want to see in your map.
This should work like a charm
MKCoordinateRegion region = MKCoordinateRegionMakeWithDistance(CLLocationCoordinate2DMake(your_lat, yout_longitude, 1000.0, 1000.0);
region.span.latitudeDelta = MAX(region.span.latitudeDelta, (coord.latitude - coord.latitude) * 1.05);
region.span.longitudeDelta = MAX(region.span.longitudeDelta, (coord.longitude + coord.longitude) * 1.05);
mapView.region = region;
I'm new to iOS, and it's so different from Android logic that I can't find how to add a marker to a map :-|
I've added a MKMapView to my xib
I've added this code to my .m (trimmed)
#import "AppDelegate.h"
#import <MapKit/MapKit.h>
#interface Dove ()
#property (weak,nonatomic) IBOutlet MKMapView *mappa;
#end
#define METERS_PER_MILE 1609.344
#implementation Dove
- (IBAction)vaiHome:(id)sender {
Index *second = [[Index alloc] initWithNibName:#"Index" bundle:nil];
[self presentViewController:second animated:YES completion:nil];
}
- (void)viewDidLoad
{
[super viewDidLoad];
CLLocationCoordinate2D zoomLocation;
zoomLocation.latitude = 45.40170;
zoomLocation.longitude= 8.91552;
MKCoordinateRegion viewRegion = MKCoordinateRegionMakeWithDistance(zoomLocation, METERS_PER_MILE, METERS_PER_MILE);
[_mappa setRegion:viewRegion animated:YES];
[_mappa regionThatFits:viewRegion];
}
Now, how can I display a pin at that position? It should simple, but I can't find a solution :-|
Also, the map remain in united states but it most go to the marker.
Thanks a lot.
First you have to setup the annotation marker (call this in your viewdidload):
- (void)setupAnnotation
{
CLLocationCoordinate2D zoomLocation;
zoomLocation.latitude = 45.40170;
zoomLocation.longitude= 8.91552;
NARMapViewAnnotation* annot = [[NARMapViewAnnotation alloc] initWithCoord:zoomLocation];
[_mapView addAnnotation:annot];
}
Then you have to setup the MKMapViewDelegate method:
- (void)mapView:(MKMapView *)mv didAddAnnotationViews:(NSArray *)views
{
MKAnnotationView* annotView = [views objectAtIndex:0];
id<MKAnnotation> mp = [annotView annotation];
MKCoordinateRegion region = [mv regionThatFits:MKCoordinateRegionMakeWithDistance([mp coordinate], REGION_WINDOW, REGION_WINDOW)];
[mv setRegion:region animated:YES];
}
NARMapViewAnnotation:
#import <Foundation/Foundation.h>
#import <MapKit/MapKit.h>
#interface NARMapViewAnnotation : NSObject <MKAnnotation>
#property (nonatomic, assign) CLLocationCoordinate2D coordinate;
- (id)initWithCoord:(CLLocationCoordinate2D)coord;
#end
#import "NARMapViewAnnotation.h"
#implementation NARMapViewAnnotation
- (id)initWithCoord:(CLLocationCoordinate2D)coord
{
if (self = [super init])
{
_coordinate = coord;
}
return self;
}
#end
I have the users location on my app, but how would I drop an annotation on the current user location? Would I have to get the long & lat of the users location and drop an annotation that way? or how would I do it?
First import the necessary frameworks (CoreLocation and MapKit).
Then create the Objective-C NSObject class Annotation
Setup its .h:
#import <Foundation/Foundation.h>
#import <CoreLocation/CoreLocation.h>
#import <MapKit/MapKit.h>
#interface Annotation : NSObject <MKAnnotation>
#property (nonatomic) CLLocationCoordinate2D coordinate;
#property (nonatomic, copy) NSString *title;
#property (nonatomic, copy) NSString *subtitle;
#end
Setup its .m:
#import "Annotation.h"
#implementation Annotation
#synthesize coordinate, title, subtitle;
#end
Setup viewDidLoad
if ([CLLocationManager locationServicesEnabled]) {
locationManager = [[CLLocationManager alloc] init];
[locationManager setDelegate:self];
[locationManager setDesiredAccuracy: kCLLocationAccuracyBestForNavigation];
[locationManager startUpdatingLocation];
}
self.mapView.delegate = self;
Setup the didUpdateToLocation
// IMPORT ANNOTATION
- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation {
[locationManager stopUpdatingLocation];
double miles = 3.10686;
double scalingFactor = ABS((cos(2 * M_PI * newLocation.coordinate.latitude / 360.0)));
MKCoordinateSpan span;
span.latitudeDelta = miles/69.0;
span.longitudeDelta = miles/(scalingFactor * 69.0);
MKCoordinateRegion region;
region.span = span;
region.center = newLocation.coordinate;
[self.mapView setRegion:region animated:YES];
Annotation *annot = [[Annotation alloc] init];
annot.coordinate = newLocation.coordinate;
[self.mapView addAnnotation:annot];
}
The simplest way is to set showsUserLocation to YES on your MKMapView and implement
- (void)mapView:(MKMapView *)mapView didUpdateUserLocation:(MKUserLocation *)userLocation {
MKCoordinateRegion region = MKCoordinateRegionMake(userLocation.location.coordinate, MKCoordinateSpanMake(0.01, 0.01));
[mapView setRegion:region animated:NO];
}
in your MKMapViewDelegate to have the map view move to that location when the user's location has been found.
This will show a blue dot on the map view at the user's location like the Maps app does.
I'm trying to zoom into the user location as the center reference for the screen. I have this code:
MainViewController.h
#import <UIKit/UIKit.h>
#import "FlipsideViewController.h"
#import <MapKit/MapKit.h>
#import <CoreLocation/CoreLocation.h>
IBOutlet MKMapView *mapView;
#interface MainViewController : UIViewController <FlipsideViewControllerDelegate, MKMapViewDelegate> {
MKMapView *mapView;
}
#property (nonatomic, retain) IBOutlet MKMapView *mapView;
MainViewController.m
#implementation MainViewController
#synthesize mapView;
- (void)viewDidLoad {
[super viewDidLoad];
mapView = [[MKMapView alloc]
initWithFrame:self.view.bounds
];
mapView.showsUserLocation = YES;
mapView.mapType = MKMapTypeHybrid;
mapView.delegate = self;
[self.view addSubview:mapView];
}
- (void)mapView:(MKMapView *)mapView didUpdateUserLocation:(MKUserLocation *)userLocation {
MKCoordinateRegion region;
MKCoordinateSpan span;
span.latitudeDelta = 0.005;
span.longitudeDelta = 0.005;
CLLocationCoordinate2D location;
location.latitude = userLocation.coordinate.latitude;
location.longitude = userLocation.coordinate.longitude;
region.span = span;
region.center = location;
[mapView setRegion:region animated:YES];
}
Now I'm only getting a build warning on the last line [mapView setRegion:region animated:YES] stating: 'local declaration of 'mapView' hides instance variable'
When you do mapView.showsUserLocation = YES;, you ask it to retrieve the user location. This doesn't happen instantly. As it takes time, the map view notifies its delegate that a user location is available via the delegate method mapView:didUpdateUserLocation. So you should adopt the MKMapViewDelegate protocol and implement that method. You should move all your zooming-in code to this method.
Setting the delegate
- (void)viewDidLoad {
[super viewDidLoad];
mapView = [[MKMapView alloc]
initWithFrame:CGRectMake(0,
0,
self.view.bounds.size.width,
self.view.bounds.size.height)
];
mapView.showsUserLocation = YES;
mapView.mapType = MKMapTypeHybrid;
mapView.delegate = self;
[self.view addSubview:mapView];
}
Updated delegate method
- (void)mapView:(MKMapView *)aMapView didUpdateUserLocation:(MKUserLocation *)aUserLocation {
MKCoordinateRegion region;
MKCoordinateSpan span;
span.latitudeDelta = 0.005;
span.longitudeDelta = 0.005;
CLLocationCoordinate2D location;
location.latitude = aUserLocation.coordinate.latitude;
location.longitude = aUserLocation.coordinate.longitude;
region.span = span;
region.center = location;
[aMapView setRegion:region animated:YES];
}
In your interface you forgot to inherit MapViewDelegate -
#import <MapKit/MapKit.h>
#interface MainViewController : UIViewController <FlipsideViewControllerDelegate, MKMapViewDelegate>
{
MKMapView *mapView;
}
#property (nonatomic, retain) IBOutlet MKMapView *mapView;
Rest seems fine.