objective-c MKMapView center on user location - ios

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.

Related

How to locate my current location in iOS?

i got this error what that error meant to be.i can't understand what error it is.
so plz help
thanks
error
1.ViewController.h
#import <UIKit/UIKit.h>
#import <MapKit/MapKit.h>
#import <CoreLocation/CoreLocation.h>
#interface ViewController : UIViewController<MKMapViewDelegate>
#property (weak, nonatomic) IBOutlet MKMapView *mycurrentlocation;
#end
2. ViewController.m
#import "ViewController.h"
#interface ViewController ()
#end
#implementation ViewController #synthesize mycurrentlocation;
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
self.mycurrentlocation.delegate = self; }
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated. }
-(void)mapView:(MKMapView *)mapView didUpdateUserLocation:(MKUserLocation *)userLocation {
MKCoordinateRegion re = MKCoordinateRegionMakeWithDistance(userLocation.coordinate, 800,
800);
[self.mycurrentlocation setRegion:[self.mycurrentlocation regionThatFits:re] animated:YES];
MKPointAnnotation *point = [[MKPointAnnotation alloc] init];
point.coordinate = userLocation.coordinate;
point.title = #"Where am I?";
point.subtitle = #"I'm here!!!";
[self.mycurrentlocation addAnnotation:point]; }
#end
Then put this line of code in the viewDidLoad method of your class:
[self.locationManager requestAlwaysAuthorization];
You need to add the core location framework and Map Kit framework.
In your AppName-Info.plist Add a new row with the key name being:
NSLocationWhenInUseUsageDescription
Or
NSLocationAlwaysUsageDescription
With the value being a string of the message that you want to be displayed:
YourAppName would like to use your location.
In your header file. (I use App Name-Prefix.pch but YourViewController.h will work too)
#define IS_OS_8_OR_LATER ([[[UIDevice currentDevice] systemVersion] floatValue] >= 8.0)
YourViewController.h
#import <MapKit/MapKit.h>
#import <MapKit/MKAnnotation.h>
#interface YourViewController : UIViewController <MKMapViewDelegate, CLLocationManagerDelegate> {
}
#property(nonatomic, retain) IBOutlet MKMapView *mapView;
#property(nonatomic, retain) CLLocationManager *locationManager;
YourViewController.m
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view.
mapView.delegate = self;
self.locationManager = [[CLLocationManager alloc] init];
self.locationManager.delegate = self;
#ifdef __IPHONE_8_0
if(IS_OS_8_OR_LATER) {
// Use one or the other, not both. Depending on what you put in info.plist
[self.locationManager requestWhenInUseAuthorization];
[self.locationManager requestAlwaysAuthorization];
}
#endif
[self.locationManager startUpdatingLocation];
mapView.showsUserLocation = YES;
[mapView setMapType:MKMapTypeStandard];
[mapView setZoomEnabled:YES];
[mapView setScrollEnabled:YES];
}
-(void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:YES];
self.locationManager.distanceFilter = kCLDistanceFilterNone;
self.locationManager.desiredAccuracy = kCLLocationAccuracyBest;
[self.locationManager startUpdatingLocation];
NSLog(#"%#", [self deviceLocation]);
//View Area
MKCoordinateRegion region = { { 0.0, 0.0 }, { 0.0, 0.0 } };
region.center.latitude = self.locationManager.location.coordinate.latitude;
region.center.longitude = self.locationManager.location.coordinate.longitude;
region.span.longitudeDelta = 0.005f;
region.span.longitudeDelta = 0.005f;
[mapView setRegion:region animated:YES];
}
- (void)mapView:(MKMapView *)mapView didUpdateUserLocation:(MKUserLocation *)userLocation
{
MKCoordinateRegion region = MKCoordinateRegionMakeWithDistance(userLocation.coordinate, 800, 800);
[self.mapView setRegion:[self.mapView regionThatFits:region] animated:YES];
}
- (NSString *)deviceLocation {
return [NSString stringWithFormat:#"latitude: %f longitude: %f", self.locationManager.location.coordinate.latitude, self.locationManager.location.coordinate.longitude];
}
- (NSString *)deviceLat {
return [NSString stringWithFormat:#"%f", self.locationManager.location.coordinate.latitude];
}
- (NSString *)deviceLon {
return [NSString stringWithFormat:#"%f", self.locationManager.location.coordinate.longitude];
}
- (NSString *)deviceAlt {
return [NSString stringWithFormat:#"%f", self.locationManager.location.altitude];
}

About the Tab bar button with NSMutableArray annotation in MapKit

I have created 4 type of annotation group. In the map UI, I also added a tab bar on the bottom as my button.
My tab bar is used to filter out the annotation in MapKit.
For example... I have 4 group of annotation and 4 tab bar item.
When I clicked tab bar item 1, it show only 1 group of annotation in MapKit, other group of annotation will hide/remove in MapKit but I failed to achieve this kind of work.
My code:
in MapViewController.h
#import <UIKit/UIKit.h>
#import <MapKit/MapKit.h>
#import <CoreLocation/CoreLocation.h>
#interface MapViewController : UIViewController <MKMapViewDelegate, CLLocationManagerDelegate , UITabBarDelegate>{
IBOutlet UITabBar *tabBar;
}
#property (weak, nonatomic) IBOutlet UIBarButtonItem *sidebarButton;
#property (weak, nonatomic) IBOutlet MKMapView *mapView;
#property (strong, nonatomic) CLLocationManager *locationManager;
#end
my mapViewController.m:
#import "MapViewController.h"
#import "SWRevealViewController.h"
#import "Annotation.h"
#interface MapViewController ()<CLLocationManagerDelegate>
#end
//set desitination of map
#define PENANG_LATI 5.419501;
#define PENANG_LONG 100.323264;
//shop
#define SHOP_LATI 5.419501;
#define SHOP_LONG 100.323264;
//cafe
#define CAFE_LATI 5.419917;
#define CAFE_LONG 100.322969;
//food
#define FOOD_LATI 5.419746;
#define FOOD_LONG 100.322610;
//mural
#define MURAL_LATI 5.419786;
#define MURAL_LONG 100.322510;
#define THE_SPAN 0.005f;
#implementation MapViewController
#synthesize mapView;
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
//tabBar
tabBar.delegate = self;
MKCoordinateRegion myRegion;
//Center
CLLocationCoordinate2D center;
center.latitude = PENANG_LATI;
center.longitude = PENANG_LONG;
//SPAN
MKCoordinateSpan span;
span.latitudeDelta = THE_SPAN;
span.longitudeDelta = THE_SPAN;
myRegion.center = center;
myRegion.span = span;
//set map
[mapView setRegion:myRegion animated:YES];
SWRevealViewController *revealViewController = self.revealViewController;
if ( revealViewController )
{
[self.sidebarButton setTarget: self.revealViewController];
[self.sidebarButton setAction: #selector( revealToggle: )];
[self.view addGestureRecognizer:self.revealViewController.panGestureRecognizer];
}
/*
//create coordinate
CLLocationCoordinate2D penangLocation;
penangLocation.latitude = PENANG_LATI;
penangLocation.longitude = PENANG_LONG;
Annotation * myAnnotation = [Annotation alloc];
myAnnotation.coordinate = penangLocation;
myAnnotation.title = #"THE ONE ACADEMY PENANG";
myAnnotation.subtitle = #"HELLO!! I STUDY HERE";
[self.mapView addAnnotation:myAnnotation];
*/
}
- (void)tabBar:(UITabBar *)tabBar didSelectItem:(UITabBarItem *)item
{
//my group of annotation location
NSMutableArray * myShop = [[NSMutableArray alloc] init];
NSMutableArray * myCafe = [[NSMutableArray alloc] init];
NSMutableArray * myFood = [[NSMutableArray alloc] init];
NSMutableArray * myMural = [[NSMutableArray alloc] init];
CLLocationCoordinate2D penangLocation;
Annotation * myShopAnnotation;
Annotation * myCafeAnnotation;
Annotation * myFoodAnnotation;
Annotation * myMuralAnnotation;
//shop location
myShopAnnotation = [[Annotation alloc] init];
penangLocation.latitude = SHOP_LATI;
penangLocation.longitude = SHOP_LONG;
myShopAnnotation.coordinate = penangLocation;
myShopAnnotation.title = #"Shop";
myShopAnnotation.subtitle = #"I study here";
[myShop addObject:myShopAnnotation];
//cafe location
myCafeAnnotation = [[Annotation alloc] init];
penangLocation.latitude = CAFE_LATI;
penangLocation.longitude = CAFE_LONG;
myCafeAnnotation.coordinate = penangLocation;
myCafeAnnotation.title = #"Cafe";
myCafeAnnotation.subtitle = #"I paid here";
[myCafe addObject:myCafeAnnotation];
//food location
myFoodAnnotation = [[Annotation alloc] init];
penangLocation.latitude = FOOD_LATI;
penangLocation.longitude = FOOD_LONG;
myFoodAnnotation.coordinate = penangLocation;
myFoodAnnotation.title = #"Food";
myFoodAnnotation.subtitle = #"I walk here";
[myFood addObject:myFoodAnnotation];
//Mural location
myMuralAnnotation = [[Annotation alloc] init];
penangLocation.latitude = MURAL_LATI;
penangLocation.longitude = MURAL_LONG;
myMuralAnnotation.coordinate = penangLocation;
myMuralAnnotation.title = #"Mural";
myMuralAnnotation.subtitle = #"I walk here";
[myMural addObject:myMuralAnnotation];
if(item.tag == 1)
{
//show and hide annotation
NSLog(#"shop");
[mapView addAnnotations:myShop];
[mapView removeAnnotations:myCafe];
[mapView removeAnnotations:myFood];
[mapView removeAnnotations:myMural];
}
if(item.tag == 2)
{
//show and hide annotation
NSLog(#"cafe");
[mapView removeAnnotations:myShop];
[mapView addAnnotations:myCafe];
[mapView removeAnnotations:myFood];
[mapView removeAnnotations:myMural];
}
if(item.tag == 3)
{
//show and hide annotation
NSLog(#"food");
[mapView removeAnnotations:myShop];
[mapView removeAnnotations:myCafe];
[mapView removeAnnotations:myFood];
[mapView addAnnotations:myMural];
}
if(item.tag == 4)
{
//show and hide annotation
NSLog(#"mural");
[mapView removeAnnotations:myShop];
[mapView removeAnnotations:myCafe];
[mapView removeAnnotations:myFood];
[mapView addAnnotations:myMural];
}
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#end
When removeAnnotations: is called like this:
[mapView removeAnnotations:myCafe];
the map view looks for the exact objects (using pointer comparison) in myCafe that are already on the map.
The map view here does not match up annotations using their coordinate, title, etc.
Since the code creates new instances of each annotation every time a selection is made, the new instances are not found on the map and so removeAnnotations: does nothing.
Instead, in your case, you could just tell the map view to remove all existing annotations and then add the new annotations based on the current selection.
Instead of this:
[mapView addAnnotations:myShop];
[mapView removeAnnotations:myCafe];
[mapView removeAnnotations:myFood];
[mapView removeAnnotations:myMural];
do this:
[mapView removeAnnotations:mapView.annotations]; //remove all
[mapView addAnnotations:myShop]; //then add new
The code could be simplified as well by using a switch statement and in each case, only create the annotations needed for the selection (you don't need to create all annotations every time).

Add a marker to my map

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

iOS- MKMapKit-How would I drop an annotation on the users location?

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.

MKMapKit Not Showing userLocation

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!!

Resources