Authored by Justin R. Miller

Merge branch 'develop' into arc

... ... @@ -84,7 +84,7 @@
@property (nonatomic, assign) BOOL hasBoundingBox;
/** Whether touch events for the annotation's layer are recognized. Defaults to `YES`. */
@property (nonatomic, assign) BOOL enabled;
@property (nonatomic, assign, getter=isEnabled) BOOL enabled;
/** @name Representing an Annotation Visually */
... ...
... ... @@ -130,7 +130,25 @@
- (BOOL)containsPoint:(CGPoint)thePoint
{
return CGPathContainsPoint(shapeLayer.path, nil, thePoint, [shapeLayer.fillRule isEqualToString:kCAFillRuleEvenOdd]);
BOOL containsPoint = NO;
if ([self.fillColor isEqual:[UIColor clearColor]])
{
// if shape is not filled with a color, do a simple "point on path" test
//
UIGraphicsBeginImageContext(self.bounds.size);
CGContextAddPath(UIGraphicsGetCurrentContext(), shapeLayer.path);
containsPoint = CGContextPathContainsPoint(UIGraphicsGetCurrentContext(), thePoint, kCGPathStroke);
UIGraphicsEndImageContext();
}
else
{
// else do a "path contains point" test
//
containsPoint = CGPathContainsPoint(shapeLayer.path, nil, thePoint, [shapeLayer.fillRule isEqualToString:kCAFillRuleEvenOdd]);
}
return containsPoint;
}
- (void)setLineColor:(UIColor *)newLineColor
... ...
... ... @@ -135,6 +135,8 @@
BOOL _delegateHasLayerForAnnotation;
BOOL _delegateHasWillHideLayerForAnnotation;
BOOL _delegateHasDidHideLayerForAnnotation;
BOOL _delegateHasDidSelectAnnotation;
BOOL _delegateHasDidDeselectAnnotation;
BOOL _delegateHasWillStartLocatingUser;
BOOL _delegateHasDidStopLocatingUser;
BOOL _delegateHasDidUpdateUserLocation;
... ... @@ -461,19 +463,16 @@
{
if ( ! self.viewControllerPresentingAttribution && ! _hideAttribution)
{
UIViewController *candidateViewController = self.window.rootViewController;
UIResponder *responder = self;
while ([self isDescendantOfView:candidateViewController.view])
while ((responder = [responder nextResponder]))
{
for (UIViewController *childViewController in candidateViewController.childViewControllers)
if ([self isDescendantOfView:childViewController.view])
candidateViewController = childViewController;
if ( ! [candidateViewController.childViewControllers count] || [candidateViewController isEqual:self.window.rootViewController])
if ([responder isKindOfClass:[UIViewController class]])
{
self.viewControllerPresentingAttribution = (UIViewController *)responder;
break;
}
}
self.viewControllerPresentingAttribution = candidateViewController;
}
else if (self.viewControllerPresentingAttribution && _hideAttribution)
{
... ... @@ -540,6 +539,9 @@
_delegateHasWillHideLayerForAnnotation = [_delegate respondsToSelector:@selector(mapView:willHideLayerForAnnotation:)];
_delegateHasDidHideLayerForAnnotation = [_delegate respondsToSelector:@selector(mapView:didHideLayerForAnnotation:)];
_delegateHasDidSelectAnnotation = [_delegate respondsToSelector:@selector(mapView:didSelectAnnotation:)];
_delegateHasDidDeselectAnnotation = [_delegate respondsToSelector:@selector(mapView:didDeselectAnnotation:)];
_delegateHasWillStartLocatingUser = [_delegate respondsToSelector:@selector(mapViewWillStartLocatingUser:)];
_delegateHasDidStopLocatingUser = [_delegate respondsToSelector:@selector(mapViewDidStopLocatingUser:)];
_delegateHasDidUpdateUserLocation = [_delegate respondsToSelector:@selector(mapView:didUpdateUserLocation:)];
... ... @@ -1659,10 +1661,8 @@
- (void)tapOnAnnotation:(RMAnnotation *)anAnnotation atPoint:(CGPoint)aPoint
{
if (anAnnotation.layer && anAnnotation.isAnnotationOnScreen && anAnnotation.layer.canShowCallout && anAnnotation.title && ! [anAnnotation isEqual:_currentAnnotation])
{
[self performSelector:@selector(popupCalloutViewForAnnotation:) withObject:anAnnotation afterDelay:1.0/3.0]; // allows for MapKit-like delay
}
if (anAnnotation.isEnabled && ! [anAnnotation isEqual:_currentAnnotation])
[self selectAnnotation:anAnnotation animated:YES];
if (_delegateHasTapOnAnnotation && anAnnotation)
{
... ... @@ -1688,21 +1688,64 @@
return [super hitTest:point withEvent:event];
}
- (void)selectAnnotation:(RMAnnotation *)annotation animated:(BOOL)animated
- (void)selectAnnotation:(RMAnnotation *)anAnnotation animated:(BOOL)animated
{
if ( ! annotation && _currentAnnotation)
if ( ! anAnnotation && _currentAnnotation)
{
[self deselectAnnotation:_currentAnnotation animated:animated];
if (annotation.isAnnotationOnScreen && ! [annotation isEqual:_currentAnnotation])
}
else if (anAnnotation.isEnabled && ! [anAnnotation isEqual:_currentAnnotation])
{
[self deselectAnnotation:_currentAnnotation animated:NO];
[self popupCalloutViewForAnnotation:annotation animated:animated];
_currentAnnotation = anAnnotation;
if (anAnnotation.layer.canShowCallout && anAnnotation.title)
{
_currentCallout = [SMCalloutView new];
_currentCallout.title = anAnnotation.title;
_currentCallout.subtitle = anAnnotation.subtitle;
_currentCallout.calloutOffset = anAnnotation.layer.calloutOffset;
if (anAnnotation.layer.leftCalloutAccessoryView)
{
if ([anAnnotation.layer.leftCalloutAccessoryView isKindOfClass:[UIControl class]])
[anAnnotation.layer.leftCalloutAccessoryView addGestureRecognizer:[[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tapOnCalloutAccessoryWithGestureRecognizer:)]];
_currentCallout.leftAccessoryView = anAnnotation.layer.leftCalloutAccessoryView;
}
if (anAnnotation.layer.rightCalloutAccessoryView)
{
if ([anAnnotation.layer.rightCalloutAccessoryView isKindOfClass:[UIControl class]])
[anAnnotation.layer.rightCalloutAccessoryView addGestureRecognizer:[[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tapOnCalloutAccessoryWithGestureRecognizer:)]];
_currentCallout.rightAccessoryView = anAnnotation.layer.rightCalloutAccessoryView;
}
_currentCallout.delegate = self;
[_currentCallout presentCalloutFromRect:anAnnotation.layer.bounds
inLayer:anAnnotation.layer
constrainedToLayer:self.layer
permittedArrowDirections:SMCalloutArrowDirectionDown
animated:animated];
}
[self correctPositionOfAllAnnotations];
anAnnotation.layer.zPosition = _currentCallout.layer.zPosition = MAXFLOAT;
if (_delegateHasDidSelectAnnotation)
[_delegate mapView:self didSelectAnnotation:anAnnotation];
}
}
- (void)deselectAnnotation:(RMAnnotation *)annotation animated:(BOOL)animated
{
if ([annotation isEqual:_currentAnnotation] && _currentCallout)
if ([annotation isEqual:_currentAnnotation])
{
[_currentCallout dismissCalloutAnimated:animated];
... ... @@ -1713,13 +1756,15 @@
_currentAnnotation = nil;
_currentCallout = nil;
if (_delegateHasDidDeselectAnnotation)
[_delegate mapView:self didDeselectAnnotation:annotation];
}
}
- (void)setSelectedAnnotation:(RMAnnotation *)selectedAnnotation
{
if ( ! [selectedAnnotation isEqual:_currentAnnotation])
[self selectAnnotation:selectedAnnotation animated:YES];
[self selectAnnotation:selectedAnnotation animated:YES];
}
- (RMAnnotation *)selectedAnnotation
... ... @@ -1727,51 +1772,6 @@
return _currentAnnotation;
}
- (void)popupCalloutViewForAnnotation:(RMAnnotation *)anAnnotation
{
[self popupCalloutViewForAnnotation:anAnnotation animated:YES];
}
- (void)popupCalloutViewForAnnotation:(RMAnnotation *)anAnnotation animated:(BOOL)animated
{
_currentAnnotation = anAnnotation;
_currentCallout = [SMCalloutView new];
_currentCallout.title = anAnnotation.title;
_currentCallout.subtitle = anAnnotation.subtitle;
_currentCallout.calloutOffset = anAnnotation.layer.calloutOffset;
if (anAnnotation.layer.leftCalloutAccessoryView)
{
if ([anAnnotation.layer.leftCalloutAccessoryView isKindOfClass:[UIControl class]])
[anAnnotation.layer.leftCalloutAccessoryView addGestureRecognizer:[[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tapOnCalloutAccessoryWithGestureRecognizer:)]];
_currentCallout.leftAccessoryView = anAnnotation.layer.leftCalloutAccessoryView;
}
if (anAnnotation.layer.rightCalloutAccessoryView)
{
if ([anAnnotation.layer.rightCalloutAccessoryView isKindOfClass:[UIControl class]])
[anAnnotation.layer.rightCalloutAccessoryView addGestureRecognizer:[[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tapOnCalloutAccessoryWithGestureRecognizer:)]];
_currentCallout.rightAccessoryView = anAnnotation.layer.rightCalloutAccessoryView;
}
_currentCallout.delegate = self;
[self correctPositionOfAllAnnotations];
anAnnotation.layer.zPosition = _currentCallout.layer.zPosition = MAXFLOAT;
[_currentCallout presentCalloutFromRect:anAnnotation.layer.bounds
inLayer:anAnnotation.layer
constrainedToLayer:self.layer
permittedArrowDirections:SMCalloutArrowDirectionDown
animated:animated];
}
- (NSTimeInterval)calloutView:(SMCalloutView *)calloutView delayForRepositionWithSize:(CGSize)offset
{
[self registerMoveEventByUser:NO];
... ... @@ -2779,10 +2779,10 @@
// markers above shapes
//
if ( [annotation1.layer isKindOfClass:[RMMarker class]] && [@[[RMShape class], [RMCircle class]] containsObject:[annotation2.layer class]])
if ( [annotation1.layer isKindOfClass:[RMMarker class]] && ! [annotation2.layer isKindOfClass:[RMMarker class]])
return NSOrderedDescending;
if ( [@[[RMShape class], [RMCircle class]] containsObject:[annotation1.layer class]] && [annotation2.layer isKindOfClass:[RMMarker class]])
if ( ! [annotation1.layer isKindOfClass:[RMMarker class]] && [annotation2.layer isKindOfClass:[RMMarker class]])
return NSOrderedAscending;
// the rest in increasing y-position
... ...
... ... @@ -66,6 +66,20 @@ typedef enum : NSUInteger {
* @param annotation The annotation whose layer was hidden. */
- (void)mapView:(RMMapView *)mapView didHideLayerForAnnotation:(RMAnnotation *)annotation;
/** Tells the delegate that one of its annotations was selected.
*
* You can use this method to track changes in the selection state of annotations.
* @param mapView The map view containing the annotation.
* @param annotation The annotation that was selected. */
- (void)mapView:(RMMapView *)mapView didSelectAnnotation:(RMAnnotation *)annotation;
/** Tells the delegate that one of its annotations was deselected.
*
* You can use this method to track changes in the selection state of annotations.
* @param mapView The map view containing the annotation.
* @param annotation The annotation that was deselected. */
- (void)mapView:(RMMapView *)mapView didDeselectAnnotation:(RMAnnotation *)annotation;
/** @name Responding to Map Position Changes */
/** Tells the delegate when a map is about to move.
... ... @@ -143,7 +157,7 @@ typedef enum : NSUInteger {
* @param map The map view. */
- (void)doubleTapOnLabelForAnnotation:(RMAnnotation *)annotation onMap:(RMMapView *)map;
/** Tells the delegate that the user tapped one of the annotation view’s accessory buttons.
/** Tells the delegate that the user tapped one of the annotation layer's accessory buttons.
*
* Accessory views contain custom content and are positioned on either side of the annotation title text. If a view you specify is a descendant of the UIControl class, the map view calls this method as a convenience whenever the user taps your view. You can use this method to respond to taps and perform any actions associated with that control. For example, if your control displayed additional information about the annotation, you could use this method to present a modal panel with that information.
*
... ...
... ... @@ -426,7 +426,25 @@
- (BOOL)containsPoint:(CGPoint)thePoint
{
return CGPathContainsPoint(shapeLayer.path, nil, thePoint, [shapeLayer.fillRule isEqualToString:kCAFillRuleEvenOdd]);
BOOL containsPoint = NO;
if ([self.fillColor isEqual:[UIColor clearColor]])
{
// if shape is not filled with a color, do a simple "point on path" test
//
UIGraphicsBeginImageContext(self.bounds.size);
CGContextAddPath(UIGraphicsGetCurrentContext(), shapeLayer.path);
containsPoint = CGContextPathContainsPoint(UIGraphicsGetCurrentContext(), thePoint, kCGPathStroke);
UIGraphicsEndImageContext();
}
else
{
// else do a "path contains point" test
//
containsPoint = CGPathContainsPoint(shapeLayer.path, nil, thePoint, [shapeLayer.fillRule isEqualToString:kCAFillRuleEvenOdd]);
}
return containsPoint;
}
- (void)closePath
... ...