• Aucun résultat trouvé

Being a MapView Delegate

Dans le document Chapter 1. A Simple iPhone Application (Page 106-109)

When Whereami launches, the user will be shown a map around the current location and be able to tag the location by entering a name in the UITextField.

Core Location will get the latitude and longitude of the current location and create an object to represent it. WhereamiAppDelegate will then annotate the MKMapView at that location. In effect, the user will label locations that have been visited for future reference.

An MKMapView knows how to use Core Location to place the user’s location on itself; you do not have to use Core Location directly when dealing with this type of object. If you set the showsUserLocation property of an MKMapView to YES, it will show the location of the user on the map. At the end of application:didFinis hLaunchingWithOptions:, replace the message that tells the locationManager to update its location with one that tells the MKMapView to show the current location.

- (BOOL)application:(UIApplication *)application

didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {

locationManager = [[CLLocationManager alloc] init];

[locationManager setDelegate:self];

[locationManager setDistanceFilter:kCLDistanceFilterNone];

[locationManager setDesiredAccuracy:kCLLocationAccuracyBest];

// [locationManager startUpdatingLocation];

[mapView setShowsUserLocation:YES];

[window makeKeyAndVisible];

return YES;

}

Build and run the application. A few moments after the application launches, the map will display a blue annotation dot on your current location. (If you are using the simulator, the current location is always Apple’s Headquarters.) However, because you are still looking at the entire world, that blue dot is the size of Brazil and not exactly useful for figuring out where you are! Clearly, the application needs to zoom in closer to the current location.

To fix this problem, you could send some message to mapView telling it to zoom in on a region, but when would you do that? You can’t do it when the application starts because mapView needs a moment to figure out where the user is. Nor do you want to continually tell the MKMapView to update its viewing region; that would be a waste of time.

Instead, how about delegation? MKMapView has a delegate – the WhereamiAppDelegate instance. So, first, declare that the WhereamiAppDelegate instance conforms to that protocol in WhereamiAppDelegate.h:

@interface WhereamiAppDelegate : NSObject

<UIApplicationDelegate, CLLocationManagerDelegate, MKMapViewDelegate>

{

When an annotation is added to the map (like the blue dot that represents the user’s current location), the map view should zoom in on a small area around the annotation. In the protocol documentation for MKMapViewDelegate, try to find a delegate method that will do that (Figure 5.6).

Figure 5.6. MKMapViewDelegate Protocol Reference

One method sticks out here: mapView:didAddAnnotationViews:. The documentation explains what the message name already makes rather clear – mapView:didAddAnnotationViews: will be called whenever an annotation is added to the map. This method can initiate the zoom any time an annotation is added. In WhereamiAppDelegate.m, implement mapView:didAddAnnotationViews:

- (void)mapView:(MKMapView *)mv didAddAnnotationViews:(NSArray *) views

{ MKAnnotationView *annotationView = [views objectAtIndex:0];

id <MKAnnotation> mp

= [annotationView annotation];

MKCoordinateRegion region = MKCoordinateRegionMakeWithDistance([

mp coordinate], 250, 250);

[mv setRegion:region animated:YES];

}

Take a closer look at this method body. You will need an MKCoordinateRegion

to send to the MKMapView’s method setRegion:animated:. The MKCoordinateRegion is a structure (not an Objective-C object), so you can’t send it messages. To create a region, you call the function

MKCoordinateRegionMakeWithDistance with the center and two distances:

meters east-west and meters north-south. The coordinate of the annotation is passed along with the number of meters the region spans.

Skip the type declaration of the variable mp for a moment and focus on the array access. When the message mapView:didAddAnnotationViews: is sent to the delegate, an NSArray of MKAnnotationViews is also passed as an argument. This array contains all of the views that were just added to the map.

An MKAnnotationView is a view that is displayed on the MKMapView. It has a pointer to an object that contains the name, coordinate, and other annotation data. Here are where things get fun: the object that MKAnnotationView points to can be any object that conforms to the MKAnnotation protocol. You don’t have to worry about what kind of object the annotation is; you know that you can send it the messages in the MKAnnotation protocol, and, therefore, its data can be used by an MKAnnotationView. (There may be more objects in the views array, depending on how many annotations were added to the map. In this simple exercise, you only care about the first one.)

Why is MKAnnotation a protocol and not a class? Any object can conform to a protocol, and that lets your application display different types of objects on one map. Imagine an application that maps everything in a neighborhood including restaurants and movie theaters. A restaurant has a menu, and a theater has a list of showtimes; they are different types of objects. However, both can be displayed on the map if they conform to MKAnnotation. It’s brilliant!

Now consider the variable mp. Its type is id, which means “any Objective-C object.” The angled brackets further specify “as long it conforms to this protocol.”

The MKAnnotation protocol says you can send the message coordinate to any conforming object, and it will return a CLLocationCoordinate2D structure. Here you use that structure to set the center of the region. Then, you hand the region off to the MKMapView with setRegion:animated: to do the zoom.

Build and run the application again. When the map figures out where you are in the world, it zooms in on that location.

Dans le document Chapter 1. A Simple iPhone Application (Page 106-109)

Documents relatifs