diff --git a/ios/RCTMGL.xcodeproj/project.pbxproj b/ios/RCTMGL.xcodeproj/project.pbxproj index dde637d..9a5e501 100644 --- a/ios/RCTMGL.xcodeproj/project.pbxproj +++ b/ios/RCTMGL.xcodeproj/project.pbxproj @@ -28,8 +28,8 @@ C4EAF1241F606F7C0016DEE8 /* CameraMode.m in Sources */ = {isa = PBXBuildFile; fileRef = C4EAF1231F606F7C0016DEE8 /* CameraMode.m */; }; C4EAF1271F6083C70016DEE8 /* CameraUpdateItem.m in Sources */ = {isa = PBXBuildFile; fileRef = C4EAF1261F6083C70016DEE8 /* CameraUpdateItem.m */; }; C4EAF12A1F6084920016DEE8 /* CameraUpdateQueue.m in Sources */ = {isa = PBXBuildFile; fileRef = C4EAF1291F6084920016DEE8 /* CameraUpdateQueue.m */; }; - C4EAF17D1F6324970016DEE8 /* RCTSource.m in Sources */ = {isa = PBXBuildFile; fileRef = C4EAF17C1F6324970016DEE8 /* RCTSource.m */; }; - C4EAF1801F6324A80016DEE8 /* RCTLayer.m in Sources */ = {isa = PBXBuildFile; fileRef = C4EAF17F1F6324A80016DEE8 /* RCTLayer.m */; }; + C4EAF17D1F6324970016DEE8 /* RCTMGLSource.m in Sources */ = {isa = PBXBuildFile; fileRef = C4EAF17C1F6324970016DEE8 /* RCTMGLSource.m */; }; + C4EAF1801F6324A80016DEE8 /* RCTMGLLayer.m in Sources */ = {isa = PBXBuildFile; fileRef = C4EAF17F1F6324A80016DEE8 /* RCTMGLLayer.m */; }; C4EAF1831F6336E20016DEE8 /* RCTMGLVectorSource.m in Sources */ = {isa = PBXBuildFile; fileRef = C4EAF1821F6336E20016DEE8 /* RCTMGLVectorSource.m */; }; C4EAF1891F633C010016DEE8 /* RCTMGLVectorSourceManager.m in Sources */ = {isa = PBXBuildFile; fileRef = C4EAF1881F633C010016DEE8 /* RCTMGLVectorSourceManager.m */; }; C4EAF18F1F633E020016DEE8 /* RCTMGLFillLayer.m in Sources */ = {isa = PBXBuildFile; fileRef = C4EAF18E1F633E020016DEE8 /* RCTMGLFillLayer.m */; }; @@ -106,10 +106,10 @@ C4EAF1261F6083C70016DEE8 /* CameraUpdateItem.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CameraUpdateItem.m; sourceTree = ""; }; C4EAF1281F6084920016DEE8 /* CameraUpdateQueue.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CameraUpdateQueue.h; sourceTree = ""; }; C4EAF1291F6084920016DEE8 /* CameraUpdateQueue.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CameraUpdateQueue.m; sourceTree = ""; }; - C4EAF17B1F6324970016DEE8 /* RCTSource.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTSource.h; sourceTree = ""; }; - C4EAF17C1F6324970016DEE8 /* RCTSource.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTSource.m; sourceTree = ""; }; - C4EAF17E1F6324A80016DEE8 /* RCTLayer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTLayer.h; sourceTree = ""; }; - C4EAF17F1F6324A80016DEE8 /* RCTLayer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTLayer.m; sourceTree = ""; }; + C4EAF17B1F6324970016DEE8 /* RCTMGLSource.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTMGLSource.h; sourceTree = ""; }; + C4EAF17C1F6324970016DEE8 /* RCTMGLSource.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTMGLSource.m; sourceTree = ""; }; + C4EAF17E1F6324A80016DEE8 /* RCTMGLLayer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTMGLLayer.h; sourceTree = ""; }; + C4EAF17F1F6324A80016DEE8 /* RCTMGLLayer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTMGLLayer.m; sourceTree = ""; }; C4EAF1811F6336E20016DEE8 /* RCTMGLVectorSource.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTMGLVectorSource.h; sourceTree = ""; }; C4EAF1821F6336E20016DEE8 /* RCTMGLVectorSource.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTMGLVectorSource.m; sourceTree = ""; }; C4EAF1871F633C010016DEE8 /* RCTMGLVectorSourceManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTMGLVectorSourceManager.h; sourceTree = ""; }; @@ -304,8 +304,8 @@ C4EAF1791F6320AA0016DEE8 /* Sources */ = { isa = PBXGroup; children = ( - C4EAF17B1F6324970016DEE8 /* RCTSource.h */, - C4EAF17C1F6324970016DEE8 /* RCTSource.m */, + C4EAF17B1F6324970016DEE8 /* RCTMGLSource.h */, + C4EAF17C1F6324970016DEE8 /* RCTMGLSource.m */, C4EAF1811F6336E20016DEE8 /* RCTMGLVectorSource.h */, C4EAF1821F6336E20016DEE8 /* RCTMGLVectorSource.m */, C4EAF1871F633C010016DEE8 /* RCTMGLVectorSourceManager.h */, @@ -325,8 +325,8 @@ C4EAF17A1F6320B10016DEE8 /* Layers */ = { isa = PBXGroup; children = ( - C4EAF17E1F6324A80016DEE8 /* RCTLayer.h */, - C4EAF17F1F6324A80016DEE8 /* RCTLayer.m */, + C4EAF17E1F6324A80016DEE8 /* RCTMGLLayer.h */, + C4EAF17F1F6324A80016DEE8 /* RCTMGLLayer.m */, C4EAF18D1F633E020016DEE8 /* RCTMGLFillLayer.h */, C4EAF18E1F633E020016DEE8 /* RCTMGLFillLayer.m */, C4EAF1901F6341520016DEE8 /* RCTMGLFillLayerManager.h */, @@ -417,7 +417,7 @@ buildActionMask = 2147483647; files = ( C4FB12581F79C0270055AE1F /* RCTMGLBackgroundLayer.m in Sources */, - C4EAF1801F6324A80016DEE8 /* RCTLayer.m in Sources */, + C4EAF1801F6324A80016DEE8 /* RCTMGLLayer.m in Sources */, C4EAF1271F6083C70016DEE8 /* CameraUpdateItem.m in Sources */, C4D144531F4E190C00396F26 /* MGLModule.m in Sources */, C43CA50A1F50C145000B9CB7 /* RCTMGLEvent.m in Sources */, @@ -450,7 +450,7 @@ C4EAF1891F633C010016DEE8 /* RCTMGLVectorSourceManager.m in Sources */, C4FB122D1F7972A00055AE1F /* RCTMGLRasterSource.m in Sources */, C410D5D81F7AD0C100CF822A /* RCTMGLLightManager.m in Sources */, - C4EAF17D1F6324970016DEE8 /* RCTSource.m in Sources */, + C4EAF17D1F6324970016DEE8 /* RCTMGLSource.m in Sources */, C4FB11131F71EC9F0055AE1F /* RCTMGLSymbolLayerManager.m in Sources */, C4C87A601F844C820064AE95 /* FilterParser.m in Sources */, C4EAF12A1F6084920016DEE8 /* CameraUpdateQueue.m in Sources */, diff --git a/ios/RCTMGL/MGLModule.m b/ios/RCTMGL/MGLModule.m index 5083843..8463369 100644 --- a/ios/RCTMGL/MGLModule.m +++ b/ios/RCTMGL/MGLModule.m @@ -9,7 +9,7 @@ #import "MGLModule.h" #import "RCTMGLEventTypes.h" #import "CameraMode.h" -#import "RCTSource.h" +#import "RCTMGLSource.h" @import Mapbox; @implementation MGLModule diff --git a/ios/RCTMGL/RCTMGLBackgroundLayer.h b/ios/RCTMGL/RCTMGLBackgroundLayer.h index ce3abef..ed264d3 100644 --- a/ios/RCTMGL/RCTMGLBackgroundLayer.h +++ b/ios/RCTMGL/RCTMGLBackgroundLayer.h @@ -6,9 +6,9 @@ // Copyright © 2017 Mapbox Inc. All rights reserved. // -#import "RCTLayer.h" +#import "RCTMGLLayer.h" @import Mapbox; -@interface RCTMGLBackgroundLayer : RCTLayer +@interface RCTMGLBackgroundLayer : RCTMGLLayer @end diff --git a/ios/RCTMGL/RCTMGLCircleLayer.h b/ios/RCTMGL/RCTMGLCircleLayer.h index 0dcecb4..e48afc8 100644 --- a/ios/RCTMGL/RCTMGLCircleLayer.h +++ b/ios/RCTMGL/RCTMGLCircleLayer.h @@ -6,9 +6,9 @@ // Copyright © 2017 Mapbox Inc. All rights reserved. // -#import "RCTLayer.h" +#import "RCTMGLLayer.h" -@interface RCTMGLCircleLayer : RCTLayer +@interface RCTMGLCircleLayer : RCTMGLLayer @property (nonatomic, copy) NSString *sourceLayerID; diff --git a/ios/RCTMGL/RCTMGLFillExtrusionLayer.h b/ios/RCTMGL/RCTMGLFillExtrusionLayer.h index a164a2f..acfcec2 100644 --- a/ios/RCTMGL/RCTMGLFillExtrusionLayer.h +++ b/ios/RCTMGL/RCTMGLFillExtrusionLayer.h @@ -6,10 +6,10 @@ // Copyright © 2017 Mapbox Inc. All rights reserved. // -#import "RCTLayer.h" +#import "RCTMGLLayer.h" @import Mapbox; -@interface RCTMGLFillExtrusionLayer : RCTLayer +@interface RCTMGLFillExtrusionLayer : RCTMGLLayer @property (nonatomic, copy) NSString *sourceLayerID; diff --git a/ios/RCTMGL/RCTMGLFillLayer.h b/ios/RCTMGL/RCTMGLFillLayer.h index 633a1f8..fadec38 100644 --- a/ios/RCTMGL/RCTMGLFillLayer.h +++ b/ios/RCTMGL/RCTMGLFillLayer.h @@ -6,9 +6,9 @@ // Copyright © 2017 Mapbox Inc. All rights reserved. // -#import "RCTLayer.h" +#import "RCTMGLLayer.h" @import Mapbox; -@interface RCTMGLFillLayer : RCTLayer +@interface RCTMGLFillLayer : RCTMGLLayer @end diff --git a/ios/RCTMGL/RCTMGLLayer.h b/ios/RCTMGL/RCTMGLLayer.h new file mode 100644 index 0000000..ee76688 --- /dev/null +++ b/ios/RCTMGL/RCTMGLLayer.h @@ -0,0 +1,45 @@ +// +// BaseLayer.h +// RCTMGL +// +// Created by Nick Italiano on 9/8/17. +// Copyright © 2017 Mapbox Inc. All rights reserved. +// + +#import +#import + +@import Mapbox; + +@interface RCTMGLLayer : UIView + +@property (nonatomic, weak) RCTBridge *bridge; + +@property (nonatomic, strong) MGLStyleLayer *styleLayer; +@property (nonatomic, strong) MGLStyle *style; +@property (nonatomic, strong) NSDictionary *reactStyle; +@property (nonatomic, strong) NSString *filter; + +@property (nonatomic, copy) NSString *id; +@property (nonatomic, copy) NSString *sourceID; + +@property (nonatomic, copy) NSString *aboveLayerID; +@property (nonatomic, copy) NSString *belowLayerID; +@property (nonatomic, copy) NSNumber *layerIndex; + +@property (nonatomic, copy) NSNumber *maxZoomLevel; +@property (nonatomic, copy) NSNumber *minZoomLevel; + +- (void)addToMap:(MGLStyle*)style; +- (void)removeFromMap:(MGLStyle*)style; +- (T)makeLayer:(MGLStyle*)style; +- (void)addStyles; +- (void)insertAbove:(MGLStyleLayer*)layer; +- (void)insertBelow:(MGLStyleLayer*)layer; +- (void)insertAtIndex:(NSUInteger)index; +- (void)insertLayer; +- (void)setZoomBounds; +- (void)addImage:(NSString*)url; +- (NSPredicate*)buildFilters; + +@end diff --git a/ios/RCTMGL/RCTMGLLayer.m b/ios/RCTMGL/RCTMGLLayer.m new file mode 100644 index 0000000..0cc59d7 --- /dev/null +++ b/ios/RCTMGL/RCTMGLLayer.m @@ -0,0 +1,188 @@ +// +// BaseLayer.m +// RCTMGL +// +// Created by Nick Italiano on 9/8/17. +// Copyright © 2017 Mapbox Inc. All rights reserved. +// + +#import "RCTMGLLayer.h" +#import "RCTMGLSource.h" +#import "RCTMGLStyleValue.h" +#import "RCTMGLUtils.h" +#import "FilterParser.h" + +@implementation RCTMGLLayer + +- (void)setMinZoomLevel:(NSNumber*)minZoomLevel +{ + _minZoomLevel = minZoomLevel; + + if (_styleLayer != nil) { + _styleLayer.minimumZoomLevel = [_minZoomLevel doubleValue]; + } +} + +- (void)setMaxZoomLevel:(NSNumber*)maxZoomLevel +{ + _maxZoomLevel = maxZoomLevel; + + if (_styleLayer != nil) { + _styleLayer.maximumZoomLevel = [_maxZoomLevel doubleValue]; + } +} + +- (void)setAboveLayerID:(NSString *)aboveLayerID +{ + if (_aboveLayerID != nil && _aboveLayerID == aboveLayerID) { + return; + } + + _aboveLayerID = aboveLayerID; + if (_styleLayer != nil) { + [self removeFromMap:_style]; + [self insertAbove:[_style layerWithIdentifier:aboveLayerID]]; + } +} + +- (void)setBelowLayerID:(NSString *)belowLayerID +{ + if (_belowLayerID != nil && _belowLayerID == belowLayerID) { + return; + } + + _belowLayerID = belowLayerID; + if (_styleLayer != nil) { + [self removeFromMap:_style]; + [self insertBelow:[_style layerWithIdentifier:belowLayerID]]; + } +} + +- (void)setLayerIndex:(NSNumber *)layerIndex +{ + if (_layerIndex != nil && _layerIndex == layerIndex) { + return; + } + + _layerIndex = layerIndex; + if (_styleLayer != nil) { + [self removeFromMap:_style]; + [self insertAtIndex:(NSUInteger)_layerIndex]; + } +} + +-(void)setReactStyle:(NSDictionary *)reactStyle +{ + _reactStyle = reactStyle; + + if (_styleLayer != nil) { + [self addStyles]; + } +} + +- (void)addToMap:(MGLStyle *)style +{ + _style = style; + + if ([RCTMGLSource isDefaultSource:_sourceID]) { + _styleLayer = [style layerWithIdentifier:_id]; + } else { + _styleLayer = [self makeLayer:style]; + [self insertLayer]; + } + + [self addStyles]; +} + +- (void)removeFromMap:(MGLStyle *)style +{ + [style removeLayer:_styleLayer]; +} + +- (MGLStyleLayer*)makeLayer:(MGLStyle*)style +{ + @throw [NSException exceptionWithName:NSInternalInconsistencyException + reason:[NSString stringWithFormat:@"You must override %@ in a subclass", NSStringFromSelector(_cmd)] + userInfo:nil]; +} + +- (void)addStyles +{ + @throw [NSException exceptionWithName:NSInternalInconsistencyException + reason:[NSString stringWithFormat:@"You must override %@ in a subclass", NSStringFromSelector(_cmd)] + userInfo:nil]; +} + +- (void)insertLayer +{ + if (_aboveLayerID != nil) { + [self insertAbove:[_style layerWithIdentifier:_aboveLayerID]]; + } else if (_belowLayerID != nil) { + [self insertBelow:[_style layerWithIdentifier:_belowLayerID]]; + } else if (_layerIndex != nil) { + [self insertAtIndex:(NSUInteger)_layerIndex]; + } else { + [_style addLayer:_styleLayer]; + } + + [self setZoomBounds]; +} + +- (void)setZoomBounds +{ + if (_maxZoomLevel != nil) { + _styleLayer.maximumZoomLevel = [_maxZoomLevel doubleValue]; + } + + if (_minZoomLevel != nil) { + _styleLayer.minimumZoomLevel = [_minZoomLevel doubleValue]; + } +} + +-(void)insertAbove:(MGLStyleLayer*)layer +{ + if (![self _hasInitialized]) { + return; + } + [_style insertLayer:_styleLayer aboveLayer:layer]; +} + +-(void)insertBelow:(MGLStyleLayer*)layer +{ + if (![self _hasInitialized]) { + return; + } + [_style insertLayer:_styleLayer belowLayer:layer]; +} + +-(void)insertAtIndex:(NSUInteger)index +{ + if (![self _hasInitialized]) { + return; + } + [_style insertLayer:_styleLayer atIndex:index]; +} + +- (void)addImage:(NSString *)url +{ + if (url == nil) { + return; + } + [RCTMGLUtils fetchImage:_bridge url:url callback:^(NSError *error, UIImage *image) { + if (image != nil) { + [_style setImage:image forName:url]; + } + }]; +} + +- (NSPredicate*)buildFilters +{ + return [FilterParser parse:_filter]; +} + +- (BOOL)_hasInitialized +{ + return _style != nil && _styleLayer != nil; +} + +@end diff --git a/ios/RCTMGL/RCTMGLLineLayer.h b/ios/RCTMGL/RCTMGLLineLayer.h index 215a576..db5edae 100644 --- a/ios/RCTMGL/RCTMGLLineLayer.h +++ b/ios/RCTMGL/RCTMGLLineLayer.h @@ -6,10 +6,10 @@ // Copyright © 2017 Mapbox Inc. All rights reserved. // -#import "RCTLayer.h" +#import "RCTMGLLayer.h" @import Mapbox; -@interface RCTMGLLineLayer : RCTLayer +@interface RCTMGLLineLayer : RCTMGLLayer @property (nonatomic, copy) NSString *sourceLayerID; diff --git a/ios/RCTMGL/RCTMGLMapView.h b/ios/RCTMGL/RCTMGLMapView.h index 82299b5..9e7b4a4 100644 --- a/ios/RCTMGL/RCTMGLMapView.h +++ b/ios/RCTMGL/RCTMGLMapView.h @@ -7,7 +7,7 @@ // #import -#import "RCTSource.h" +#import "RCTMGLSource.h" #import "RCTMGLLight.h" @import Mapbox; @@ -18,7 +18,7 @@ @property (nonatomic, strong) CameraUpdateQueue *cameraUpdateQueue; @property (nonatomic, strong) NSMutableArray> *reactSubviews; -@property (nonatomic, strong) NSMutableArray *sources; +@property (nonatomic, strong) NSMutableArray *sources; @property (nonatomic, strong) RCTMGLLight *light; @property (nonatomic, assign) BOOL animated; diff --git a/ios/RCTMGL/RCTMGLMapView.m b/ios/RCTMGL/RCTMGLMapView.m index 572e845..d4577e3 100644 --- a/ios/RCTMGL/RCTMGLMapView.m +++ b/ios/RCTMGL/RCTMGLMapView.m @@ -31,10 +31,10 @@ static double const M2PI = M_PI * 2; - (void) addToMap:(id)subview { - if ([subview isKindOfClass:[RCTSource class]]) { - RCTSource *source = (RCTSource*)subview; + if ([subview isKindOfClass:[RCTMGLSource class]]) { + RCTMGLSource *source = (RCTMGLSource*)subview; source.map = self; - [_sources addObject:(RCTSource*)subview]; + [_sources addObject:(RCTMGLSource*)subview]; } else if ([subview isKindOfClass:[RCTMGLLight class]]) { RCTMGLLight *light = (RCTMGLLight*)subview; _light = light; @@ -50,8 +50,8 @@ static double const M2PI = M_PI * 2; - (void) removeFromMap:(id)subview { - if ([subview isKindOfClass:[RCTSource class]]) { - RCTSource *source = (RCTSource*)subview; + if ([subview isKindOfClass:[RCTMGLSource class]]) { + RCTMGLSource *source = (RCTMGLSource*)subview; source.map = nil; [_sources removeObject:source]; } else { diff --git a/ios/RCTMGL/RCTMGLMapViewManager.m b/ios/RCTMGL/RCTMGLMapViewManager.m index d198158..5aa27f1 100644 --- a/ios/RCTMGL/RCTMGLMapViewManager.m +++ b/ios/RCTMGL/RCTMGLMapViewManager.m @@ -35,8 +35,15 @@ RCT_EXPORT_MODULE(RCTMGLMapView) mapView.delegate = self; // setup map gesture recongizers + UITapGestureRecognizer *doubleTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:nil]; + doubleTap.numberOfTapsRequired = 2; + UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(didTapMap:)]; + [tap requireGestureRecognizerToFail:doubleTap]; + UILongPressGestureRecognizer *longPress = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(didLongPressMap:)]; + + [mapView addGestureRecognizer:doubleTap]; [mapView addGestureRecognizer:tap]; [mapView addGestureRecognizer:longPress]; @@ -263,7 +270,7 @@ RCT_EXPORT_METHOD(setCamera:(nonnull NSNumber*)reactTag if (reactMapView.sources.count > 0) { for (int i = 0; i < reactMapView.sources.count; i++) { - RCTSource *source = reactMapView.sources[i]; + RCTMGLSource *source = reactMapView.sources[i]; source.map = reactMapView; } } diff --git a/ios/RCTMGL/RCTMGLRasterLayer.h b/ios/RCTMGL/RCTMGLRasterLayer.h index 9dac481..af47421 100644 --- a/ios/RCTMGL/RCTMGLRasterLayer.h +++ b/ios/RCTMGL/RCTMGLRasterLayer.h @@ -6,9 +6,9 @@ // Copyright © 2017 Mapbox Inc. All rights reserved. // -#import "RCTLayer.h" +#import "RCTMGLLayer.h" @import Mapbox; -@interface RCTMGLRasterLayer : RCTLayer +@interface RCTMGLRasterLayer : RCTMGLLayer @end diff --git a/ios/RCTMGL/RCTMGLRasterSource.h b/ios/RCTMGL/RCTMGLRasterSource.h index d2d336a..b59fbcd 100644 --- a/ios/RCTMGL/RCTMGLRasterSource.h +++ b/ios/RCTMGL/RCTMGLRasterSource.h @@ -6,10 +6,10 @@ // Copyright © 2017 Mapbox Inc. All rights reserved. // -#import "RCTSource.h" +#import "RCTMGLSource.h" @import Mapbox; -@interface RCTMGLRasterSource : RCTSource +@interface RCTMGLRasterSource : RCTMGLSource @property (nonatomic, copy) NSString *url; @property (nonatomic, copy) NSString *attribution; diff --git a/ios/RCTMGL/RCTMGLShapeSource.h b/ios/RCTMGL/RCTMGLShapeSource.h index aa6f5e3..33fee31 100644 --- a/ios/RCTMGL/RCTMGLShapeSource.h +++ b/ios/RCTMGL/RCTMGLShapeSource.h @@ -6,10 +6,10 @@ // Copyright © 2017 Mapbox Inc. All rights reserved. // -#import "RCTSource.h" +#import "RCTMGLSource.h" @import Mapbox; -@interface RCTMGLShapeSource : RCTSource +@interface RCTMGLShapeSource : RCTMGLSource @property (nonatomic, copy) NSString *url; @property (nonatomic, copy) NSString *shape; diff --git a/ios/RCTMGL/RCTMGLSource.h b/ios/RCTMGL/RCTMGLSource.h new file mode 100644 index 0000000..cb48bcc --- /dev/null +++ b/ios/RCTMGL/RCTMGLSource.h @@ -0,0 +1,31 @@ +// +// BaseSource.h +// RCTMGL +// +// Created by Nick Italiano on 9/8/17. +// Copyright © 2017 Mapbox Inc. All rights reserved. +// + +#import +#import "RCTMGLLayer.h" +#import +@import Mapbox; + +@interface RCTMGLSource : UIView + +extern NSString *const DEFAULT_SOURCE_ID; + +@property (nonatomic, strong) NSMutableArray> *reactSubviews; +@property (nonatomic, strong) NSMutableArray *layers; +@property (nonatomic, strong) MGLSource *source; +@property (nonatomic, strong) MGLMapView *map; + +@property (nonatomic, copy) NSString *id; + +- (void)addToMap; +- (void)removeFromMap; +- (MGLSource*)makeSource; + ++ (BOOL)isDefaultSource:(NSString*)sourceID; + +@end diff --git a/ios/RCTMGL/RCTMGLSource.m b/ios/RCTMGL/RCTMGLSource.m new file mode 100644 index 0000000..edf7084 --- /dev/null +++ b/ios/RCTMGL/RCTMGLSource.m @@ -0,0 +1,120 @@ +// +// BaseSource.m +// RCTMGL +// +// Created by Nick Italiano on 9/8/17. +// Copyright © 2017 Mapbox Inc. All rights reserved. +// + +#import "RCTMGLSource.h" +#import "UIView+React.h" + +@implementation RCTMGLSource + +NSString *const DEFAULT_SOURCE_ID = @"composite"; + +- (instancetype)initWithFrame:(CGRect)frame +{ + if (self = [super initWithFrame:frame]) { + _layers = [[NSMutableArray alloc] init]; + _reactSubviews = [[NSMutableArray alloc] init]; + } + return self; +} + +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wobjc-missing-super-calls" +- (void)insertReactSubview:(id)subview atIndex:(NSInteger)atIndex { + if ([subview isKindOfClass:[RCTMGLLayer class]]) { + RCTMGLLayer *layer = (RCTMGLLayer*)subview; + + if (_map.style != nil) { + [layer addToMap:_map.style]; + } + + [_layers addObject:layer]; + [_reactSubviews insertObject:layer atIndex:atIndex]; + } +} +#pragma clang diagnostic pop + +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wobjc-missing-super-calls" +- (void)removeReactSubview:(id)subview { + if ([subview isKindOfClass:[RCTMGLLayer class]]) { + RCTMGLLayer *layer = (RCTMGLLayer*)subview; + [layer removeFromMap:_map.style]; + [_layers removeObject:layer]; + [_reactSubviews removeObject:layer]; + } +} +#pragma clang diagnostic pop + +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wobjc-missing-super-calls" +- (NSArray> *)reactSubviews { + return _reactSubviews; +} +#pragma clang diagnostic pop + +- (void)setMap:(MGLMapView *)map +{ + if (map == nil) { + [self removeFromMap]; + _map = nil; + } else { + _map = map; + [self addToMap]; + } +} + +- (void)addToMap +{ + if (_map.style == nil) { + return; + } + + if ([RCTMGLSource isDefaultSource:_id]) { + _source = [_map.style sourceWithIdentifier:DEFAULT_SOURCE_ID]; + } else { + _source = [self makeSource]; + [_map.style addSource:_source]; + } + + if (_layers.count > 0) { + for (int i = 0; i < _layers.count; i++) { + RCTMGLLayer *layer = [_layers objectAtIndex:i]; + [layer addToMap:_map.style]; + } + } +} + +- (void)removeFromMap +{ + if (_map.style == nil) { + return; + } + + for (int i = 0; i < _layers.count; i++) { + RCTMGLLayer *layer = [_layers objectAtIndex:i]; + [layer removeFromMap:_map.style]; + } + + if (![RCTMGLSource isDefaultSource:_id]) { + [_map.style removeSource:_source]; + } +} + +- (MGLSource*)makeSource +{ + @throw [NSException exceptionWithName:NSInternalInconsistencyException + reason:[NSString stringWithFormat:@"You must override %@ in a subclass", NSStringFromSelector(_cmd)] + userInfo:nil]; +} + ++ (BOOL)isDefaultSource:(NSString *)sourceID +{ + return [sourceID isEqualToString:DEFAULT_SOURCE_ID]; +} + +@end diff --git a/ios/RCTMGL/RCTMGLSymbolLayer.h b/ios/RCTMGL/RCTMGLSymbolLayer.h index 85499c7..b0f879e 100644 --- a/ios/RCTMGL/RCTMGLSymbolLayer.h +++ b/ios/RCTMGL/RCTMGLSymbolLayer.h @@ -6,9 +6,9 @@ // Copyright © 2017 Mapbox Inc. All rights reserved. // -#import "RCTLayer.h" +#import "RCTMGLLayer.h" -@interface RCTMGLSymbolLayer : RCTLayer +@interface RCTMGLSymbolLayer : RCTMGLLayer @property (nonatomic, copy) NSString *sourceLayerID; diff --git a/ios/RCTMGL/RCTMGLVectorSource.h b/ios/RCTMGL/RCTMGLVectorSource.h index dc6ebe3..945a9ef 100644 --- a/ios/RCTMGL/RCTMGLVectorSource.h +++ b/ios/RCTMGL/RCTMGLVectorSource.h @@ -6,10 +6,10 @@ // Copyright © 2017 Mapbox Inc. All rights reserved. // -#import "RCTSource.h" +#import "RCTMGLSource.h" @import Mapbox; -@interface RCTMGLVectorSource : RCTSource +@interface RCTMGLVectorSource : RCTMGLSource @property (nonatomic, assign) NSString *url;