Improvements to docs & user location framework.

* Cleans up & documents more APIs, especially in location.
 * Moves `coordinate` internal and makes use of `location` to retrieve it.
 * Moves `title` & `subtitle` internal since part of `MGLAnnotation` protocol.
 * Enables `isUpdating` by privately associating weakly with a map view.
This commit is contained in:
Justin R. Miller
2015-04-02 16:58:24 -07:00
parent 7c05f941a8
commit 9a416c449c
6 changed files with 73 additions and 39 deletions

View File

@@ -251,20 +251,21 @@
#pragma mark - Displaying the User's Location
/** @name Displaying the User's Location */
/** A Boolean value indicating whether the map may display the user location.
This property does not indicate whether the user’s position is actually visible on the map, only whether the map view is allowed to display it. To determine whether the user’s position is visible, use the userLocationVisible property. The default value of this property is `NO`.
Setting this property to `YES` causes the map view to use the Core Location framework to find the current location. As long as this property is `YES`, the map view continues to track the user’s location and update it periodically.
On iOS 8 and above, your app must specify a value for `NSLocationWhenInUseUsageDescription` in its `Info.plist` to satisfy the requirements of the underlying Core Location framework when enabling this property.
*/
*
* This property does not indicate whether the user’s position is actually visible on the map, only whether the map view is allowed to display it. To determine whether the user’s position is visible, use the userLocationVisible property. The default value of this property is `NO`.
*
* Setting this property to `YES` causes the map view to use the Core Location framework to find the current location. As long as this property is `YES`, the map view continues to track the user’s location and update it periodically.
*
* On iOS 8 and above, your app must specify a value for `NSLocationWhenInUseUsageDescription` or `NSLocationAlwaysUsageDescription` in its `Info.plist` to satisfy the requirements of the underlying Core Location framework when enabling this property. */
@property (nonatomic, assign) BOOL showsUserLocation;
/// Returns a Boolean value indicating whether the user currently sees the user location annotation.
/** A Boolean value indicating whether the device’s current location is visible in the map view. (read-only) */
@property (nonatomic, assign, readonly, getter=isUserLocationVisible) BOOL userLocationVisible;
/// Returns the annotation object indicating the user’s current location.
/** Returns the annotation object indicating the user’s current location. */
@property (nonatomic, readonly) MGLUserLocation *userLocation;
/** The mode used to track the user location. */
@@ -374,23 +375,42 @@
#pragma mark - Tracking the User Location
/// Tells the delegate that the map view will begin tracking the user’s location.
/** Tells the delegate that the map view will begin tracking the user’s location.
*
* This method is called when the value of the showsUserLocation property changes to `YES`.
*
* @param mapView The map view that is tracking the user’s location. */
- (void)mapViewWillStartLocatingUser:(MGLMapView *)mapView;
/// Tells the delegate that the map view has stopped tracking the user’s location.
/** Tells the delegate that the map view has stopped tracking the user’s location.
*
* This method is called when the value of the showsUserLocation property changes to `NO`.
*
* @param mapView The map view that is tracking the user’s location. */
- (void)mapViewDidStopLocatingUser:(MGLMapView *)mapView;
/// Tells the delegate that the map view has updated the user’s location to the given location.
/** Tells the delegate that the location of the user was updated.
*
* While the showsUserLocation property is set to `YES`, this method is called whenever a new location update is received by the map view. This method is also called if the map view’s user tracking mode is set to MGLUserTrackingModeFollowWithHeading and the heading changes.
*
* This method is not called if the application is currently running in the background. If you want to receive location updates while running in the background, you must use the Core Location framework.
*
* @param mapView The map view that is tracking the user’s location.
* @param userLocation The location object representing the user’s latest location. This property may be `nil`. */
- (void)mapView:(MGLMapView *)mapView didUpdateUserLocation:(MGLUserLocation *)userLocation;
/// Tells the delegate that the map view has failed to locate the user.
/** Tells the delegate that an attempt to locate the user’s position failed.
* @param mapView The map view that is tracking the user’s location.
* @param error An error object containing the reason why location tracking failed. */
- (void)mapView:(MGLMapView *)mapView didFailToLocateUserWithError:(NSError *)error;
/**
Tells the delegate that the map view’s user tracking mode has changed.
This method is called after the map view asynchronously changes to reflect the new user tracking mode, for example by beginning to zoom or rotate.
*/
/** Tells the delegate that the map view’s user tracking mode has changed.
*
* This method is called after the map view asynchronously changes to reflect the new user tracking mode, for example by beginning to zoom or rotate.
*
* @param mapView The map view that changed its tracking mode.
* @param mode The new tracking mode.
* @param animated Whether the change caused an animated effect on the map. */
- (void)mapView:(MGLMapView *)mapView didChangeUserTrackingMode:(MGLUserTrackingMode)mode animated:(BOOL)animated;
#pragma mark - Managing Annotations

View File

@@ -1,9 +1,12 @@
#import <Foundation/Foundation.h>
/// The degree to which the map view tracks the user’s location.
/** The mode used to track the user location on the map. */
typedef NS_ENUM(NSUInteger, MGLUserTrackingMode)
{
MGLUserTrackingModeNone = 0, ///< does not track the user’s location or heading
MGLUserTrackingModeFollow = 1, ///< tracks the user’s location
MGLUserTrackingModeFollowWithHeading = 2, ///< tracks the user’s location and heading
/** The map does not follow the user location. */
MGLUserTrackingModeNone = 0,
/** The map follows the user location. */
MGLUserTrackingModeFollow,
/** The map follows the user location and rotates when the heading changes. */
MGLUserTrackingModeFollowWithHeading
};

View File

@@ -1,9 +1,8 @@
#import "MGLAnnotation.h"
/** The MGLUserLocation class defines a specific type of annotation that identifies the user’s current location. You do not create instances of this class directly. Instead, you retrieve an existing MGLUserLocation object from the userLocation property of the map view displayed in your application. */
@interface MGLUserLocation : NSObject <MGLAnnotation>
@property (nonatomic, readonly) CLLocationCoordinate2D coordinate;
/** @name Determining the User’s Position */
/** The current location of the device. (read-only)
@@ -12,15 +11,11 @@
@property (nonatomic, readonly) CLLocation *location;
/** A Boolean value indicating whether the user’s location is currently being updated. (read-only) */
@property (nonatomic, readonly, getter=isUpdating) BOOL updating; // FIXME
@property (nonatomic, readonly, getter=isUpdating) BOOL updating;
/** The heading of the user location. (read-only)
*
* This property is `nil` if the user location tracking mode is not `RMUserTrackingModeFollowWithHeading`. */
* This property is `nil` if the user location tracking mode is not `MGLUserTrackingModeFollowWithHeading`. */
@property (nonatomic, readonly) CLHeading *heading;
@property (nonatomic, copy) NSString *title;
@property (nonatomic, copy) NSString *subtitle;
@end

View File

@@ -1,17 +1,21 @@
#import "MGLUserLocation_Private.h"
@implementation MGLUserLocation
{
CLLocationCoordinate2D _coordinate;
}
#import "MGLMapView.h"
@synthesize coordinate = _coordinate;
@interface MGLUserLocation ()
@property (nonatomic, copy) NSString *title;
@property (nonatomic, copy) NSString *subtitle;
@end
@implementation MGLUserLocation
- (instancetype)init
{
if (self = [super init])
{
_coordinate = CLLocationCoordinate2DMake(MAXFLOAT, MAXFLOAT);
_location = [[CLLocation alloc] initWithLatitude:MAXFLOAT longitude:MAXFLOAT];
}
return self;
@@ -34,11 +38,15 @@
{
[self willChangeValueForKey:@"location"];
_location = newLocation;
_coordinate = _location.coordinate;
[self didChangeValueForKey:@"location"];
}
}
- (BOOL)isUpdating
{
return self.mapView.userTrackingMode != MGLUserTrackingModeNone;
}
- (void)setHeading:(CLHeading *)newHeading
{
if (newHeading.trueHeading != _heading.trueHeading)
@@ -49,9 +57,14 @@
}
}
- (CLLocationCoordinate2D)coordinate
{
return self.location.coordinate;
}
- (NSString *)title
{
if ( ! _title) return @"Current Location";
return (_title ? _title : @"Current Location");
}
@end

View File

@@ -26,6 +26,7 @@ const CGFloat MGLTrackingDotRingWidth = 24.0;
if (self = [super init])
{
self.annotation = [[MGLUserLocation alloc] init];
self.annotation.mapView = mapView;
_mapView = mapView;
[self setupLayers];
}

View File

@@ -1,8 +1,10 @@
#import "MGLUserLocation.h"
@class MGLMapView;
@interface MGLUserLocation (Private)
@property (nonatomic, readwrite) CLLocationCoordinate2D coordinate;
@property (nonatomic, weak) MGLMapView *mapView;
@property (nonatomic, readwrite) CLLocation *location;
@property (nonatomic, readwrite) CLHeading *heading;