Challenge question-Map Zooming issue


#1

In my particular solution I can get the map to show up in the third tab, but not I am having a hard time getting it to zoom in to a GPS location. Any help would be appreciated. I know I must be missing something small that I am not seeing. Another set of eyes would be super helpful.

HypnoTimeAppDelegate.m

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
   /* self.window = [[[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]] autorelease];
    // Override point for customization after application launch.
    self.window.backgroundColor = [UIColor whiteColor];*/
    
    
    //Create the tabBarController
    UITabBarController *tabBarController = [[UITabBarController alloc]init];
    
    //Create the two view controllers
    UIViewController *vc1=[[HypnosisViewController alloc]init];
    UIViewController *vc2=[[CurrentTimeViewController alloc]init];
    UIViewController *vc3 =[[MapViewController alloc]init];
    
    //Make an array containing the two view controllers
    NSArray *viewControllers=[NSArray arrayWithObjects:vc1,vc2,vc3, nil];
    //NSArray *viewControllers=[NSArray arrayWithObjects:vc1,vc2, nil];
    
    //The view controllers array retains vc1 and vc2 and we can release our ownership of them in this method
    
    [vc1 release];
    [vc2 release];
    [vc3 release];
    
    //Attach the controllers to the tab bar
    
    [tabBarController setViewControllers:viewControllers];
    
    
    //Set tabBarController as rootViewController of Window
    [[self window]setRootViewController:tabBarController];
    
    //The window reatins the tab bar controller we can release our reference 
    [tabBarController release];
    
    
    [self.window makeKeyAndVisible];
    return YES;
}


MapViewController.h


#import <Foundation/Foundation.h>
#import <CoreLocation/CoreLocation.h>
#import <MapKit/MapKit.h>



@interface MapViewController : UIViewController <CLLocationManagerDelegate,MKMapViewDelegate>

{
IBOutlet MKMapView *worldview;
CLLocationManager *locationManager;
}

- (void) findLocation;
- (void) foundLocation :(CLLocation *) loc;

@end

MapViewController.m

#import "MapViewController.h"

@implementation MapViewController
- (id) init{
    //Call the superClass's designated initializer
    self=[super initWithNibName:@"MapViewController" 
                         bundle:nil];
    
    if(self){
        //Get the tab bar item
        UITabBarItem *tbi=[self tabBarItem];
        //Give it a label
        
        //Create a UIImage from a file
        UIImage *i =[UIImage imageNamed:@"Hypno.png"];
        
        //Put the image in the tab bar
        [tbi setImage:i];
        
        
        [tbi setTitle:@"Location"];
        
        //Create location manager object for my application
        locationManager =[[CLLocationManager alloc]init];
        [worldview setDelegate:self]; 
        //Need to set the self for the delegate in order to get zooming to work and
        // and to have the function call the method.
        
        
        
        
        //There is going to be a warning from the following line of code. Ignore for now
        [locationManager setDelegate:self];
            
        //We want all the results from the location manager
        [locationManager setDistanceFilter:kCLDistanceFilterNone];
        
        //We want it to be as accurate as possible regardless of how much time/power is required.
        [locationManager setDesiredAccuracy:kCLLocationAccuracyBest];
        
        //Tell the manager to start looking for its location immediately
        [worldview setShowsUserLocation:YES];
    }
    
    return self;
}




- (void) locationManager:(CLLocationManager *)manager 
     didUpdateToLocation:(CLLocation *)newLocation 
            fromLocation:(CLLocation *)oldLocation  {
    
    NSLog(@"Location Data:%@",newLocation);
    
    
    //If I had a developer account I could see the heading.
    // NSLog(@"Heading: %@", [locationManager heading]);
    
    //How many seconds ago was the new location created?
    NSTimeInterval t =[[newLocation timestamp]timeIntervalSinceNow];
    
    //CLLocationManagers will return the last found location  of the device first, 
    //you don't want that data in this case. If the location was made more than 3 minutes
    //ago,ignore it.
    
    if(t < -180){
        //This is cached data, you don't want it, keep looking
        return;
    }
    
    
    [self foundLocation:newLocation];
    
}





- (void)findLocation
{
    [locationManager startUpdatingLocation];
}



- (void)foundLocation:(CLLocation *)loc
{
    CLLocationCoordinate2D coord = [loc coordinate];
    
    // Zoom the region to this location
    MKCoordinateRegion region = MKCoordinateRegionMakeWithDistance(coord, 550, 550);
    [worldview setRegion:region animated:YES];
    
    [locationManager stopUpdatingLocation];
}






- (void) locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error{
    
    
    NSLog(@"Could Not Find Location: %@",error);
    
    
}




- (void)mapView:(MKMapView *)mapView didUpdateUserLocation:(MKUserLocation *)userLocation{
    
    CLLocationCoordinate2D loc=[userLocation coordinate];
    MKCoordinateRegion region= MKCoordinateRegionMakeWithDistance(loc, 550, 550);
    [worldview setRegion:region animated:YES];
    
    
}






- (void) viewDidUnload{
    NSLog(@"MapViewController view was unloaded due to a low memory warning");
    
    [super viewDidUnload];
}






- (void) viewWillAppear:(BOOL)animated{
    NSLog(@"MapViewController will appear.");
    [super viewWillAppear];
    
}




-(void) viewWillDisappear:(BOOL)animated{
    
    NSLog(@"MapViewController will disappear");
    [super viewWillDisappear];
    
}






- (id) initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil{
    
    //Ignore the parameters - nib name is an implementation detail
    return [self init];
}




//This method gets called automatically when the view is created
- (void) viewDidLoad{
    [super viewDidLoad];
    
    NSLog(@"Loaded the view for the MapViewController");
    
    //[[self view] setBackgroundColor:[UIColor yellowColor]];
    
}




- (void)dealloc{
    [super dealloc];
}

Thanks in advance! :blush:


#2

I have the same problem. I reviewed your code and it looks really similar to mine (I have a few things in different places). With that said, I can’t seem to get the map to zoom in. I created a temp project to see if I could achieve the zoom outside of this project and I had no problems in the temp project.


#3

Weird. I wonder what I am doing wrong here. I am going to keep hacking away at this a while.


#4

[quote=“roamingGeek”]Weird. I wonder what I am doing wrong here. I am going to keep hacking away at this a while.
[/quote]

I figured it out! Move [(MKMapView pointer) setShowUserLocation: YES] and [{MKMapView pointer) setDelegate:self] to -(void)viewDidLoad method and you should be all good.

I haven’t figured out why but this seems to fix the problem.

edit: it also works if you place it in the -(void)viewDidAppear method


#5

[quote=“cliffsun”][quote=“roamingGeek”]Weird. I wonder what I am doing wrong here. I am going to keep hacking away at this a while.
[/quote]

I figured it out! Move [(MKMapView pointer) setShowUserLocation: YES] and [{MKMapView pointer) setDelegate:self] to -(void)viewDidLoad method and you should be all good.

I haven’t figured out why but this seems to fix the problem.

edit: it also works if you place it in the -(void)viewDidAppear method[/quote]

Like this?

[code]//This method gets called automatically when the view is created

  • (void) viewDidLoad{
    [super viewDidLoad];

    [worldview setDelegate:self];

    //Tell the manager to start looking for its location immediately
    [worldview setShowsUserLocation:YES];

    NSLog(@“Loaded the view for the MapViewController”);

    //[[self view] setBackgroundColor:[UIColor yellowColor]];

}[/code]
It didn’t work for me… :blush: :confused: Am I missing something? Is my order off?


#6

Mystery solved. You have to wire the UIView to the view and the Mapview to your MKMapView. All working now! :smiley: :slight_smile:


#7

I had the same problem initially, and came to the same conclusion. What I don’t understand is why this is the case. I initially had:

MapViewController.m

- (id)init
{
    // ... Stuff ...

    // "mv" is my MKMapView
    [mv setDelegate:self];
    
    // ...More Stuff ...
}

And simply moved that line into the - (void)loadView method, which solved it. So why can’t I set the delegate in the initializer? Just kind of confused on that.

If I was using a xib to do this, all the delegate setting and such happens through the connections so there isn’t any issue. But since I tried to do this programmatically, it seems you can only set the delegate at certain points.