Skip to content

Commit cf9e189

Browse files
fix(standard user location annotation view): restored standard user location annotation view
The `CustomUserLocationAnnotationView` was very rudimentary and does not any functionality the standard annotation view does not offer. Besides, the custom implementation did not support the different camera modes. Therefore, it is best to use the standard annotation view.
1 parent f339929 commit cf9e189

File tree

1 file changed

+1
-310
lines changed

1 file changed

+1
-310
lines changed

src/ui-mapbox/index.ios.ts

+1-310
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,6 @@ class MGLMapViewDelegateImpl extends NSObject implements MGLMapViewDelegate {
6161
private cameraChangedListener: (reason, animated?: boolean) => void;
6262
private cameraIdledListener: () => void;
6363
private userLocationRenderMode: any;
64-
private userLocationAnnotationView: CustomUserLocationAnnotationView;
6564

6665
/**
6766
* initialize with the mapReady callback
@@ -100,7 +99,7 @@ class MGLMapViewDelegateImpl extends NSObject implements MGLMapViewDelegate {
10099
* set user location marker modes
101100
*/
102101
changeUserLocationRenderMode(userLocationRenderMode) {
103-
this.userLocationAnnotationView.changeUserLocationRenderMode(userLocationRenderMode);
102+
// nothing to do here
104103
}
105104

106105
/**
@@ -315,23 +314,6 @@ class MGLMapViewDelegateImpl extends NSObject implements MGLMapViewDelegate {
315314
}
316315
}
317316

318-
/**
319-
* override the standard location marker
320-
*/
321-
mapViewViewForAnnotation(mapView: MGLMapView, annotation: MGLAnnotation): MGLAnnotationView {
322-
if (Trace.isEnabled()) {
323-
CLog(CLogTypes.info, 'MGLMapViewDelegateImpl::mapViewViewForAnnotation() top');
324-
}
325-
326-
if (annotation.isKindOfClass(MGLUserLocation.class())) {
327-
this.userLocationAnnotationView = CustomUserLocationAnnotationView.alloc().init() as CustomUserLocationAnnotationView;
328-
329-
return this.userLocationAnnotationView;
330-
}
331-
332-
return null;
333-
}
334-
335317
mapViewRegionIsChangingWithReason(mapView: MGLMapView, reason: MGLCameraChangeReason) {
336318
if (Trace.isEnabled()) {
337319
CLog(CLogTypes.info, 'MGLMapViewDelegateImpl::mapViewRegionIsChanging()');
@@ -909,297 +891,6 @@ export class MapboxView extends MapboxViewBase {
909891
}
910892
}
911893

912-
/**
913-
* a custom user location marker
914-
*
915-
* We want to add some behavior to the user location marker to visibly
916-
* show the user when locations are being stored and when they are not.
917-
*
918-
* Sadly, it's not as easy under iOS as it is on Android. It involves
919-
* creating a custom annotation view.
920-
*
921-
* @link https://docs.mapbox.com/ios/maps/examples/user-location-annotation/
922-
*/
923-
924-
@NativeClass
925-
class CustomUserLocationAnnotationView extends MGLUserLocationAnnotationView implements MGLUserLocationAnnotationView {
926-
public size: number;
927-
public dot: CALayer;
928-
public arrow: CAShapeLayer;
929-
930-
// may be NORMAL, COMPASS, or GPS.
931-
932-
private userLocationRenderMode: string;
933-
private renderModeChanged: boolean;
934-
935-
/**
936-
* init
937-
*
938-
* @link https://docs.nativescript.org/core-concepts/ios-runtime/HelloWorld
939-
*/
940-
941-
public init() {
942-
this.size = 48;
943-
super.initWithFrame(CGRectMake(0, 0, this.size, this.size));
944-
945-
this.renderModeChanged = true;
946-
this.userLocationRenderMode = 'NORMAL';
947-
948-
return this;
949-
}
950-
951-
/**
952-
* update
953-
*
954-
* The note from the Objective-C sample indicates this method may be called quite
955-
* often so it needs to be kept lightweight.
956-
*/
957-
958-
update() {
959-
if (CLLocationCoordinate2DIsValid(this.userLocation.coordinate)) {
960-
// if it's the first time here, setup the layers that make up the
961-
// location marker.
962-
963-
if (!this.dot) {
964-
this.drawNonTrackingLocationMarker();
965-
}
966-
967-
if (this.userLocationRenderMode === 'GPS') {
968-
this.updateHeading();
969-
}
970-
}
971-
}
972-
973-
/**
974-
* Draw the GPS tracking arrow.
975-
*
976-
* @link https://docs.nativescript.org/ns-framework-modules/color
977-
*/
978-
979-
drawTrackingLocationMarker() {
980-
if (Trace.isEnabled()) {
981-
CLog(CLogTypes.info, 'CustomerUserLocationAnnotatinView::drawTrackingLocationMarker()');
982-
}
983-
984-
this.drawTrackingDot();
985-
this.drawArrow();
986-
} // end of setupLayers()
987-
988-
/**
989-
* draw the non-tracking marker
990-
*/
991-
992-
drawNonTrackingLocationMarker() {
993-
if (Trace.isEnabled()) {
994-
CLog(CLogTypes.info, 'CustomerUserLocationAnnotatinView::drawNonTrackingLocationMarker()');
995-
}
996-
997-
this.drawNonTrackingDot();
998-
999-
if (this.arrow) {
1000-
this.arrow.removeFromSuperlayer();
1001-
this.arrow = null;
1002-
}
1003-
}
1004-
1005-
/**
1006-
* draw the tracking dot.
1007-
*/
1008-
1009-
drawTrackingDot() {
1010-
this.size = 48;
1011-
1012-
// we need to adjust the size of the bounds of the marker. The Tracking marker
1013-
// is larger than the non tracking marker.
1014-
1015-
this.bounds = CGRectMake(0, 0, this.size, this.size);
1016-
1017-
const dot = CALayer.layer();
1018-
1019-
dot.frame = this.bounds;
1020-
1021-
// user corner radius to turn the layer into a circle
1022-
1023-
dot.cornerRadius = this.size / 2;
1024-
dot.backgroundColor = this.tintColor.CGColor;
1025-
dot.borderWidth = 4;
1026-
1027-
const whiteColor = new Color('#FFFFFF');
1028-
dot.borderColor = whiteColor.ios.CGColor;
1029-
1030-
if (!this.dot) {
1031-
this.layer.addSublayer(dot);
1032-
} else {
1033-
this.layer.replaceSublayerWith(this.dot, dot);
1034-
}
1035-
1036-
// QUESTION: does GC catch this?
1037-
1038-
this.dot = dot;
1039-
}
1040-
1041-
/**
1042-
* draw the non-tracking dot.
1043-
*/
1044-
1045-
drawNonTrackingDot() {
1046-
this.size = 24;
1047-
this.bounds = CGRectMake(0, 0, this.size, this.size);
1048-
const dot = CALayer.layer();
1049-
1050-
dot.frame = this.bounds;
1051-
1052-
// user corner radius to turn the layer into a circle
1053-
1054-
dot.cornerRadius = this.size / 2;
1055-
dot.backgroundColor = this.tintColor.CGColor;
1056-
1057-
dot.borderWidth = 1;
1058-
1059-
const whiteColor = new Color('#FFFFFF');
1060-
dot.borderColor = whiteColor.ios.CGColor;
1061-
1062-
if (!this.dot) {
1063-
this.layer.addSublayer(dot);
1064-
} else {
1065-
this.layer.replaceSublayerWith(this.dot, dot);
1066-
}
1067-
1068-
// QUESTION: does GC catch this?
1069-
1070-
this.dot = dot;
1071-
}
1072-
1073-
/**
1074-
* draw an arrow
1075-
*/
1076-
1077-
drawArrow() {
1078-
const arrow = CAShapeLayer.layer();
1079-
1080-
arrow.path = this.arrowPath();
1081-
arrow.frame = CGRectMake(0, 0, this.size / 2, this.size / 2);
1082-
arrow.position = CGPointMake(CGRectGetMidX(this.dot.frame), CGRectGetMidY(this.dot.frame));
1083-
arrow.fillColor = this.dot.borderColor;
1084-
1085-
if (!this.arrow) {
1086-
this.layer.addSublayer(arrow);
1087-
} else {
1088-
this.layer.replaceSublayerWith(this.arrow, arrow);
1089-
}
1090-
1091-
// QUESTION: Does GC catch this?
1092-
1093-
this.arrow = arrow;
1094-
}
1095-
1096-
/**
1097-
* update arrow heading
1098-
*
1099-
* @link https://docs.nativescript.org/core-concepts/ios-runtime/types/C-Functions
1100-
*/
1101-
1102-
updateHeading() {
1103-
// just to avoid a possible race condition where the arrow isnt' drawn yet
1104-
1105-
if (!this.arrow) {
1106-
return;
1107-
}
1108-
1109-
if (typeof this.userLocation == 'undefined') {
1110-
return;
1111-
}
1112-
1113-
if (typeof this.userLocation.heading == 'undefined' || this.userLocation.heading === null) {
1114-
return;
1115-
}
1116-
1117-
if (typeof this.userLocation.heading.trueHeading == 'undefined' || this.userLocation.heading.trueHeading === null) {
1118-
return;
1119-
}
1120-
1121-
if (this.userLocation.heading.trueHeading > 0) {
1122-
this.arrow.hidden = false;
1123-
1124-
// get the difference between the map's current direction and the
1125-
// user's heading, then convert it from degrees to radians
1126-
//
1127-
// The original Objective-C example uses the inline C function MGLRadiansFromDegrees but because
1128-
// it's declared as inline it is not available for NativeScript. See linked article above.
1129-
1130-
// let rotation : number = MGLRadiansFromDegrees( this.mapView.direction - this.userLocation.heading.trueHeading );
1131-
1132-
const degrees: number = this.mapView.direction - this.userLocation.heading.trueHeading;
1133-
1134-
// in radians
1135-
1136-
let rotation: number = (degrees * Math.PI) / 180;
1137-
1138-
rotation = -rotation;
1139-
1140-
// if the difference would be perceptible, rotate the arrow.
1141-
1142-
if (fabs(rotation) > 0.01) {
1143-
// Disable implicit animations of this rotation, which reduces lag between updates
1144-
1145-
CATransaction.begin();
1146-
CATransaction.setDisableActions(true);
1147-
1148-
this.arrow.setAffineTransform(CGAffineTransformRotate(CGAffineTransformIdentity, rotation));
1149-
1150-
CATransaction.commit();
1151-
}
1152-
} else {
1153-
this.arrow.hidden = true;
1154-
}
1155-
}
1156-
1157-
/**
1158-
* Calculate the vector path for an arrow
1159-
*/
1160-
1161-
arrowPath() {
1162-
const max: number = this.size / 2;
1163-
const pad: number = 3;
1164-
1165-
const top: CGPoint = CGPointMake(max * 0.5, 0);
1166-
const left: CGPoint = CGPointMake(0 + pad, max - pad);
1167-
const right: CGPoint = CGPointMake(max - pad, max - pad);
1168-
const center: CGPoint = CGPointMake(max * 0.5, max * 0.6);
1169-
1170-
const bezierPath = UIBezierPath.bezierPath();
1171-
bezierPath.moveToPoint(top);
1172-
bezierPath.addLineToPoint(left);
1173-
bezierPath.addLineToPoint(center);
1174-
1175-
bezierPath.addLineToPoint(right);
1176-
bezierPath.addLineToPoint(top);
1177-
bezierPath.closePath();
1178-
1179-
return bezierPath.CGPath;
1180-
}
1181-
1182-
/**
1183-
* change Render mode
1184-
*
1185-
* @param {string} renderMode
1186-
*/
1187-
1188-
changeUserLocationRenderMode(renderMode) {
1189-
if (Trace.isEnabled()) {
1190-
CLog(CLogTypes.info, "CustomUserLocationAnnotatinView::changeUserLocationRenderMode(): changing mode to '" + renderMode + "'");
1191-
}
1192-
1193-
this.userLocationRenderMode = renderMode;
1194-
1195-
if (renderMode === 'GPS') {
1196-
this.drawTrackingLocationMarker();
1197-
} else {
1198-
this.drawNonTrackingLocationMarker();
1199-
}
1200-
}
1201-
} // end of class CustomUserLocationAnnotationView
1202-
1203894
export class Mapbox extends MapboxCommon implements MapboxApi {
1204895
// reference to the native mapbox API
1205896

0 commit comments

Comments
 (0)