Sorry its a basic question, I want to know why my code doesn't need alloc/init for mapView. Does it happen automatically on retain ? I am not using ARC and on alloc/init of my MKMapView* mapView it does not result in error but the map view doesn't show the location information and also doesn't appear as hybrid type....but on removing the alloc/init statement fro viewDidLoad it works all fine !! why?
#import <UIKit/UIKit.h>
#import <CoreLocation/CoreLocation.h>
#import <MapKit/MapKit.h>
#interface MDViewController : UIViewController<CLLocationManagerDelegate, MKMapViewDelegate>
#property (retain, nonatomic) IBOutlet MKMapView* mapView;
#end
-----
#import "MDViewController.h"
#interface MDViewController ()
{
CLLocationManager* lmanager;
}
#end
#implementation MDViewController
#synthesize mapView;
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
lmanager= [[CLLocationManager alloc]init];
lmanager.delegate=self;
lmanager.desiredAccuracy=kCLLocationAccuracyBest;
lmanager.distanceFilter=kCLDistanceFilterNone;
[lmanager startUpdatingLocation];
//mapView = [[MKMapView alloc]init];//without allocating here it works
mapView.delegate=self;
mapView.mapType=MKMapTypeHybrid;
}
-(void) locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation
{
//update map
MKCoordinateSpan span;
span.latitudeDelta= .001;
span.longitudeDelta=.001;
MKCoordinateRegion region;
region.center= newLocation.coordinate;
region.span=span;
[mapView setRegion:region animated:YES];
[mapView setShowsUserLocation:YES];
}
You don't need to alloc init your mapview because it is done for you by the Xib. When loading the interface xib, the frameworks see you have a frozen mapview and alloc init it automagically, then assign that mapview to the one in your viewcontroller code.
If in your code you alloc init, you break the link between the two.
One way to make it work is to have no mapview in your IB xib and alloc init it, setDelegate, set frame and finally add its view as a subview of the main view.
I try to stay concise. I hope it us clear to you. And ARC has no relation whatsoever with all that.
Related
I want to show the user's current location on map using MapKit and everything goes ok but the user current location is not visible on the maps.
Here are the properties I have set for mapView:
Here is rest of the controller's code:
#import <MapKit/MapKit.h>
#import "ShowMarkerAndNavigateVC.h"
#interface ShowMarkerAndNavigateVC ()
#property (weak, nonatomic) IBOutlet MKMapView *mapView;
#end
CLLocationManager *mgr;
#implementation ShowMarkerAndNavigateVC
- (void)viewDidLoad {
[super viewDidLoad];
NSLog(#"View loaded Successfully");
mgr = [[CLLocationManager alloc] init];
[mgr requestWhenInUseAuthorization];
NSLog(#"Reuquested always authorization");
}
- (IBAction)backButtonPressed:(id)sender {
[self.navigationController popViewControllerAnimated:YES];
}
#end
I have also set the mapView delegate to the current controller as shown here:
The expected result is that it should show the user's current location.
The actual result is that it does not show location on the map as shown here:
First, I would suggest actually setting showsUserLocation property to YES in code.
Second, note that it is up to you to show the region where the user location actually is; for example:
- (void)mapView:(MKMapView *)mapView
didUpdateUserLocation:(MKUserLocation *)userLocation {
CLLocationCoordinate2D coordinate = userLocation.location.coordinate;
MKCoordinateRegion reg =
MKCoordinateRegionMakeWithDistance(coordinate, 600, 600);
mapView.region = reg;
}
If you're using the simulator, you won't get the user's location, because the simulator doesn’t know its own location.
To do so, open the Debug menu of the Simulator and select Apple in the ***Location* sub-menu.
Hope this will help you.
I have this code in my file,
#synthesize myLocation;
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
self.locationManager = [[CLLocationManager alloc] init];
myLocation.delegate = self;
[self.locationManager requestWhenInUseAuthorization];
[myLocation setShowsUserLocation: YES];
}
- (void)mapView:(MKMapView *)mapView didUpdateUserLocation:(MKUserLocation *)userLocation
{
MKCoordinateRegion region = MKCoordinateRegionMakeWithDistance(userLocation.coordinate, 800, 800);
[self.myLocation setRegion:[self.myLocation regionThatFits:region] animated:YES];
}
But, method didUpdateUserLocation not calling.
I already added required frameworks in app.
I added everything in info.plist file. But still it is not calling.
This is my .h file,
#import <UIKit/UIKit.h>
#import <CoreLocation/CoreLocation.h>
#import <MapKit/MapKit.h>
#interface MapView : UIViewController <MKMapViewDelegate, CLLocationManagerDelegate>
#property (weak, nonatomic) IBOutlet MKMapView *myLocation;
#property(nonatomic, retain) CLLocationManager *locationManager;
#end
I just solved the problem,
locationManager = [[CLLocationManager alloc] init];
myLocation.delegate = self;
[locationManager requestWhenInUseAuthorization];
[locationManager startUpdatingLocation];
[myLocation setShowsUserLocation: YES];
Use setShowUserLocation with value YES after startUpdatingLocation
You have not called the method to update the location yet so the delegate method is not getting called. You need to call method for startUpdatingLocation.
For Objective - C:
[locationManager startUpdatingLocation];
For Swift:
locationManager.startUpdatingLocation()
Brother I tried your code.The delegate method is not called.
Then I found out the solution you did not add below line at the end of the viewDidLoad method. Please add
[self.locationManager startUpdatingLocation];
After I added above line code in viewDidLoad method,the delegate method called successfully.
I have one problem. I've been looking at the other answers here on stack overflow about the same question and I can't get them to work for me. So I'm going to try asking here. What I want to do is when I'm on map view and have got the user location I want to automatically zoom into the location.
the h-file
#import <UIKit/UIKit.h>
#import <MapKit/MapKit.h>
#import <CoreLocation/CoreLocation.h>
#interface WalkingTableViewController: UIViewController <MKMapViewDelegate>
#property (weak, nonatomic) IBOutlet MKMapView *MKMapView;
#end
the m-file
#import "WalkingTableViewController.h"
#interface UITableViewController ()
#end
#implementation WalkingTableViewController
- (void)viewDidLoad
{
[super viewDidLoad];
self.MKMapView.showsUserLocation=YES;
self.MKMapView.delegate = self;
[self.MKMapView setUserTrackingMode:MKUserTrackingModeFollow animated:YES];
}
- (IBAction)StopButton:(id)sender
- (IBAction)StartButton:(id)sender
#end
If you like to see the zoom animated, I would place the code in the viewDidAppear method, so that the animation starts once the view controller is displayed.
- (void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
CLLocationManager* tempLocationManager = [[CLLocationManager alloc] init];
MKCoordinateRegion tRegion = MKCoordinateRegionMakeWithDistance([tempLocationManager.location coordinate], 20000, 20000);
[self.MKMapView setRegion:tRegion animated:animated];
}
Adjust the region (zoom level, 20000 in the example above) to your needs.
What you have to do is tell the mapview to zoom into a region. This should get you started:
CLLocationCoordinate2D center = _mapView.userLocation.coordinate;
MKCoordinateRegion region = MKCoordinateRegionMake(center, MKCoordinateSpanMake(2000, 2000));
[_mapView setRegion:region animated:YES];
ViewController.h
#import <UIKit/UIKit.h>
#import "MapKit/MapKit.h"
#interface ViewController : UIViewController <MKMapViewDelegate>
#property (weak, nonatomic) IBOutlet MKMapView *mapView;
#end
ViewController.m
#import "ViewController.h"
#interface ViewController ()
#end
#implementation ViewController
- (void)viewDidLoad
{
[super viewDidLoad];
//Setting Region
//MKCoordinateRegion *myRegion;
//Center
CLLocationCoordinate2D center;
center.longitude = 55.316667;
center.latitude = 25.266667;
//SPAN
MKCoordinateSpan span;
span.latitudeDelta = 0.30f;
span.longitudeDelta = 0.30f;
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#end
As you see my code seems to be fine, and normally it should show the location given in latitude and longtitude values. But instead it shows this :
I am working in Xcode 5 with iOS 6.
Any ideas about the problem?
Nowhere in the code shown does it "give the coordinates to the map view" so why should it do anything?
All the code does is:
Declares local variables called center and span in the viewDidLoad method.
Sets the values of these local variables (which the map view knows nothing about).
The viewDidLoad method ends (doing nothing with the values of the local variables).
Adding this line after setting center and span actually gives the coordinates to the map view so that it shows those coordinates:
mapView.region = MKCoordinateRegionMake(center, span);
(Assuming, of course, that the mapView IBOutlet is connected to the MKMapView in the xib.)
Now, this will center the map view at the coordinates you specified and that's it.
If you were expecting any other effects (such as a pin appearing at the coordinates), you'll need to create an annotation with those coordinates and tell the map view to add it.
I'm trying to learn how to use MKMapView and have created a sample application to do so; however, in my code I'm making a call to setRegion:animated to change the center point and the span, but the map never updates. I've run through a few threads on StackOverflow (SO) where others have mentioned similar problems and tried implementing their solutions to no avail.
Things I made sure to try in my code based on other's SO threads I found:
Ensure I initialized the MKMapView with a frame
Tried running the setRegion:animated method call on the main thread
My included my code below, can anyone shed some light on why my MKMapView instance will not update it's view?
EDIT: Correct code shown below:
MK_ViewController.h:
#import <UIKit/UIKit.h>
#import <MapKit/MapKit.h>
#interface MV_ViewController : UIViewController {
IBOutlet MKMapView *myMapView;
MKCoordinateRegion defaultRegion;
CLLocationCoordinate2D defaultCenter;
MKCoordinateSpan defaultSpan;
}
#end
MK_ViewController.m:
#import "MV_ViewController.h"
#interface MV_ViewController ()
#end
#implementation MV_ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// initialize default map view properties
defaultCenter = CLLocationCoordinate2DMake(33.732894,-118.091718);
defaultSpan = MKCoordinateSpanMake(0.028270, 0.0465364);
// Setup MapView's inital region
defaultRegion = MKCoordinateRegionMake(defaultCenter, defaultSpan);
// create the map view
CGRect screenRect = [[UIScreen mainScreen] bounds];
myMapView = [[MKMapView alloc] initWithFrame:screenRect];
}
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
// update map's initial view
[myMapView setRegion:defaultRegion animated:YES];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#end
MK_ViewController+MKMapViewDelegate.m:
#import "MV_ViewController.h"
#implementation MV_ViewController (MKMapViewDelegate)
- (void)mapView:(MKMapView *)mapView regionDidChangeAnimated:(BOOL)animated {
MKCoordinateRegion region = mapView.region;
CLLocationCoordinate2D center = region.center;
MKCoordinateSpan span = region.span;
NSLog(#"Center (lat,lon): (%f,%f)",center.latitude,center.longitude);
NSLog(#"Span (lat,lon): (%f,%f)",span.latitudeDelta,span.longitudeDelta);
}
#end
I solved the issue by removing the MKViewMap object from the NIB, and instead added it using the following code in the MK_ViewController.m file:
[self.view addSubView:myMapView];
The issue was that the NIB wasn't properly wired up to the view controller, and the view controller was creating it's own map view.
Thank you #Jason Cabot for pointing me in the right direction.