AMAnnotationView.m 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240
  1. //
  2. // AMAnnotationView.m
  3. // Apex Mobile
  4. //
  5. // Created by Jack on 2018/5/3.
  6. // Copyright © 2018年 United Software Applications, Inc. All rights reserved.
  7. //
  8. #import "AMAnnotationView.h"
  9. #import "AMMapAnnotaion.h"
  10. @interface AMAnnotationView ()
  11. @property (strong,nonatomic) UIView *calloutView;
  12. @property (strong,nonatomic) AMMapAnnotaion *myAnnotation;
  13. @property (nonatomic,strong) UILabel *titleLabel;
  14. @property (nonatomic,strong) UILabel *detailLabel;
  15. @property (nonatomic,assign) BOOL tapedCallout;
  16. @end
  17. @implementation AMAnnotationView
  18. - (instancetype)initWithAnnotation:(id<MKAnnotation>)annotation reuseIdentifier:(NSString *)reuseIdentifier {
  19. if (self = [super initWithAnnotation:annotation reuseIdentifier:reuseIdentifier]) {
  20. self.opaque = NO;
  21. self.canShowCallout = NO;
  22. self.myAnnotation = (AMMapAnnotaion *)annotation;
  23. self.calloutView = [[UIView alloc] init];
  24. self.calloutView.backgroundColor = [UIColor whiteColor];
  25. }
  26. return self;
  27. }
  28. - (UILabel *)titleLabel {
  29. if (!_titleLabel) {
  30. _titleLabel = [[UILabel alloc] init];
  31. _titleLabel.font = [UIFont boldSystemFontOfSize:16.0f];
  32. _titleLabel.textColor = [UIColor blackColor];
  33. _titleLabel.textAlignment = NSTextAlignmentLeft;
  34. _titleLabel.lineBreakMode = NSLineBreakByTruncatingTail;
  35. _titleLabel.numberOfLines = 1;
  36. }
  37. return _titleLabel;
  38. }
  39. - (UILabel *)detailLabel {
  40. if (!_detailLabel) {
  41. _detailLabel = [[UILabel alloc] init];
  42. _detailLabel.font = [UIFont systemFontOfSize:14.0f];
  43. _detailLabel.textColor = [UIColor blackColor];
  44. _detailLabel.textAlignment = NSTextAlignmentLeft;
  45. _detailLabel.lineBreakMode = NSLineBreakByTruncatingTail;
  46. _detailLabel.numberOfLines = 0;
  47. }
  48. return _detailLabel;
  49. }
  50. - (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event {
  51. UIView *hitView = [super hitTest:point withEvent:event];
  52. self.tapedCallout = NO;
  53. if (self.isSelected) {
  54. if (hitView) {
  55. // self.canDeselected = NO;
  56. return self;
  57. }
  58. if (CGRectContainsPoint(self.calloutView.frame, point)) {
  59. // hitView = self.calloutView;
  60. self.tapedCallout = YES;
  61. return self.calloutView;
  62. }
  63. }
  64. return hitView;
  65. }
  66. - (void)setSelected:(BOOL)selected animated:(BOOL)animated {
  67. if (self.isSelected && self.tapedCallout) {
  68. if (self.delegate && [self.delegate respondsToSelector:@selector(mapView:didTapAnnotaionCallout:)]) {
  69. [self.delegate mapView:[self findMap:self] didTapAnnotaionCallout:self.myAnnotation];
  70. }
  71. }
  72. [super setSelected:selected animated:YES];
  73. // Get the custom callout view.
  74. UIView *calloutView = self.calloutView;
  75. if (selected) {
  76. NSString *title = self.myAnnotation.title;
  77. NSString *detail = self.myAnnotation.subtitle;
  78. CGFloat maxWidth = [UIScreen mainScreen].bounds.size.width * 0.8f;
  79. CGFloat w0 = maxWidth;
  80. CGRect frame = CGRectZero;
  81. self.titleLabel.text = title;
  82. [self.titleLabel sizeToFit];
  83. frame = self.titleLabel.bounds;
  84. frame.origin = CGPointMake(5, 5);
  85. w0 = CGRectGetWidth(frame);
  86. if (w0 > maxWidth) {
  87. w0 = maxWidth;
  88. frame.size.width = w0;
  89. }
  90. self.titleLabel.frame = frame;
  91. [self.calloutView addSubview:self.titleLabel];
  92. CGFloat w1 = maxWidth;
  93. self.detailLabel.text = detail;
  94. [self.detailLabel sizeToFit];
  95. frame.origin.y = CGRectGetMaxY(frame) + 5;
  96. frame.size = self.detailLabel.bounds.size;
  97. w1 = CGRectGetWidth(frame);
  98. if (w1 > maxWidth) {
  99. w1 = maxWidth;
  100. frame.size.width = w1;
  101. }
  102. self.detailLabel.frame = frame;
  103. [self.calloutView addSubview:self.detailLabel];
  104. CGFloat h = CGRectGetMaxY(frame) + 5 + 10;
  105. MKMapView *map = [self findMap:self];
  106. // frame = self.frame;
  107. //
  108. // // 将左右边距小于30的移动30
  109. // if (frame.origin.x < 30) {
  110. //
  111. // if (map != nil) {
  112. // MKCoordinateRegion region = map.region;
  113. // CGPoint center = map.center;
  114. // center.x -= 30;
  115. // region.center = [map convertPoint:center toCoordinateFromView:map];
  116. // [map setRegion:region animated:NO];
  117. // }
  118. // }
  119. // if (CGRectGetMaxX(frame) > CGRectGetWidth(map.bounds) - 30) {
  120. // if (map != nil) {
  121. // MKCoordinateRegion region = map.region;
  122. // CGPoint center = map.center;
  123. // center.x += 30;
  124. // region.center = [map convertPoint:center toCoordinateFromView:map];
  125. // [map setRegion:region animated:NO];
  126. // }
  127. //
  128. // }
  129. //
  130. // if (CGRectGetMinY(frame) < h) {
  131. // if (map != nil) {
  132. //
  133. // MKCoordinateRegion region = map.region;
  134. // CGPoint center = map.center;
  135. // center.y += h + CGRectGetHeight(frame);
  136. // region.center = [map convertPoint:center toCoordinateFromView:map];
  137. // [map setRegion:region animated:NO];
  138. //
  139. // }
  140. // }
  141. CGPoint center = self.center;
  142. MKCoordinateRegion region = map.region;
  143. region.center = [map convertPoint:center toCoordinateFromView:map];
  144. [map setRegion:region animated:NO];
  145. frame = self.frame;
  146. CGFloat w = MAX(w0, w1) + 5 * 2;
  147. self.calloutView.frame = CGRectMake((CGRectGetWidth(frame) - w) * 0.5, -h, w, h);
  148. UIBezierPath *path = [self pathForCalloutWithWidth:w Height:h Anchor:CGPointMake(w * 0.5, h)];
  149. CAShapeLayer *mask = [CAShapeLayer layer];
  150. mask.fillColor = [UIColor blackColor].CGColor;
  151. mask.shadowColor = [UIColor blackColor].CGColor;
  152. mask.shadowOffset = CGSizeMake(2, 2);
  153. mask.path = path.CGPath;
  154. self.calloutView.layer.mask = mask;
  155. [self addSubview:calloutView];
  156. } else {
  157. [calloutView removeFromSuperview];
  158. }
  159. }
  160. - (MKMapView *)findMap:(UIView *)view {
  161. if (view == nil) {
  162. return nil;
  163. }
  164. if (view.superview == nil) {
  165. if ([view isKindOfClass:[MKMapView class]]) {
  166. return (MKMapView *)view;
  167. } else {
  168. return nil;
  169. }
  170. }
  171. if (view.superview && [view.superview isKindOfClass:[MKMapView class]]) {
  172. return (MKMapView *)view.superview;
  173. } else {
  174. return [self findMap:view.superview];
  175. }
  176. }
  177. - (UIBezierPath *)pathForCalloutWithWidth:(CGFloat)w Height:(CGFloat)h Anchor:(CGPoint)anchor {
  178. UIBezierPath *path = [UIBezierPath bezierPath];
  179. [path moveToPoint:CGPointMake(w * 0.5, 0)];
  180. [path addLineToPoint:CGPointMake(w - 5, 0)];
  181. [path addQuadCurveToPoint:CGPointMake(w, 5) controlPoint:CGPointMake(w, 0)];
  182. [path addLineToPoint:CGPointMake(w, h - 15)];
  183. [path addQuadCurveToPoint:CGPointMake(w - 5, h - 10) controlPoint:CGPointMake(w, h - 10)];
  184. // [path addLineToPoint:CGPointMake(anchor.x + 10, h - 10)];
  185. // [path addQuadCurveToPoint:anchor controlPoint:CGPointMake(anchor.x + 5, h - 10)];
  186. // [path addQuadCurveToPoint:CGPointMake(anchor.x - 10, h - 10) controlPoint:CGPointMake(anchor.x - 5, h - 10)];
  187. [path addLineToPoint:CGPointMake(anchor.x + 6, h - 10)];
  188. [path addLineToPoint:anchor];
  189. [path addLineToPoint:CGPointMake(anchor.x - 6, h - 10)];
  190. [path addLineToPoint:CGPointMake(5, h - 10)];
  191. [path addQuadCurveToPoint:CGPointMake(0, h - 15) controlPoint:CGPointMake(0, h - 10)];
  192. [path addLineToPoint:CGPointMake(0, 5)];
  193. [path addQuadCurveToPoint:CGPointMake(5, 0) controlPoint:CGPointMake(0, 0)];
  194. [path addLineToPoint:CGPointMake(w * 0.5, 0)];
  195. return path;
  196. }
  197. @end