From 70c6792f777f8fa9c1ab5f876ec0988634ccbaeb Mon Sep 17 00:00:00 2001 From: Daniel Schmidt Date: Sun, 29 Mar 2015 22:05:03 +0200 Subject: [PATCH 1/6] added pins to react component part --- Libraries/Components/MapView/MapView.js | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/Libraries/Components/MapView/MapView.js b/Libraries/Components/MapView/MapView.js index b778fc695bd758..d8506c95bc5a1d 100644 --- a/Libraries/Components/MapView/MapView.js +++ b/Libraries/Components/MapView/MapView.js @@ -111,6 +111,16 @@ var MapView = React.createClass({ */ legalLabelInsets: EdgeInsetsPropType, + /** + * Pins displayed on the map, with a title, latitude and longitude + */ + pins: React.PropTypes.arrayOf(React.PropTypes.shape({ + title: React.PropTypes.string, + subtitle: React.PropTypes.string, + latitude: React.PropTypes.number.isRequired, + longitude: React.PropTypes.number.isRequired, + })), + /** * Callback that is called continuously when the user is dragging the map. */ @@ -145,6 +155,7 @@ var MapView = React.createClass({ maxDelta={this.props.maxDelta} minDelta={this.props.minDelta} legalLabelInsets={this.props.legalLabelInsets} + pins={this.props.pins} onChange={this._onChange} onTouchStart={this.props.onTouchStart} /> From bf08c9bc35318a725c628e4e8efa4edd340a6743 Mon Sep 17 00:00:00 2001 From: Daniel Schmidt Date: Mon, 30 Mar 2015 17:02:03 +0200 Subject: [PATCH 2/6] WIP --- React/Views/RCTMap.h | 1 + React/Views/RCTMapManager.m | 5 +++++ 2 files changed, 6 insertions(+) diff --git a/React/Views/RCTMap.h b/React/Views/RCTMap.h index 3850378e99e4f0..a280da4918fbd2 100644 --- a/React/Views/RCTMap.h +++ b/React/Views/RCTMap.h @@ -23,5 +23,6 @@ extern const CGFloat RCTMapZoomBoundBuffer; @property (nonatomic, assign) CGFloat maxDelta; @property (nonatomic, assign) UIEdgeInsets legalLabelInsets; @property (nonatomic, strong) NSTimer *regionChangeObserveTimer; +@property (nonatomic, strong) NSArray *pins; @end diff --git a/React/Views/RCTMapManager.m b/React/Views/RCTMapManager.m index 9bd0f7eab81fd2..186cb1ca75cc3c 100644 --- a/React/Views/RCTMapManager.m +++ b/React/Views/RCTMapManager.m @@ -70,6 +70,7 @@ - (UIView *)view RCT_EXPORT_VIEW_PROPERTY(minDelta, CGFloat) RCT_EXPORT_VIEW_PROPERTY(legalLabelInsets, UIEdgeInsets) RCT_EXPORT_VIEW_PROPERTY(region, MKCoordinateRegion) +RCT_EXPORT_VIEW_PROPERTY(pins, NSDictionaryArray) #pragma mark MKMapViewDelegate @@ -89,6 +90,8 @@ - (void)mapView:(RCTMap *)mapView didUpdateUserLocation:(MKUserLocation *)locati - (void)mapView:(RCTMap *)mapView regionWillChangeAnimated:(BOOL)animated { + //Supported types: http://facebook.github.io/react-native/docs/nativemodulesios.html#argument-types + NSLog(@"It's me2: %@", _pins); [self _regionChanged:mapView]; mapView.regionChangeObserveTimer = [NSTimer timerWithTimeInterval:RCTMapRegionChangeObserveInterval @@ -97,6 +100,8 @@ - (void)mapView:(RCTMap *)mapView regionWillChangeAnimated:(BOOL)animated userInfo:@{ @"mapView": mapView } repeats:YES]; [[NSRunLoop mainRunLoop] addTimer:mapView.regionChangeObserveTimer forMode:NSRunLoopCommonModes]; + + // TODO: Add pins here (http://www.appcoda.com/ios-programming-101-drop-a-pin-on-map-with-mapkit-api/) } - (void)mapView:(RCTMap *)mapView regionDidChangeAnimated:(BOOL)animated From 41ef1a1076598e5ab66b32f322a1abe5a272c293 Mon Sep 17 00:00:00 2001 From: Daniel Banck Date: Mon, 30 Mar 2015 22:45:59 +0200 Subject: [PATCH 3/6] Pins are now accessible inside RCTMapManager --- Libraries/Components/MapView/MapView.js | 1 + React/Views/RCTMap.h | 2 +- React/Views/RCTMap.m | 9 +++++++++ React/Views/RCTMapManager.m | 1 - 4 files changed, 11 insertions(+), 2 deletions(-) diff --git a/Libraries/Components/MapView/MapView.js b/Libraries/Components/MapView/MapView.js index d8506c95bc5a1d..8e9a97a6bf80ac 100644 --- a/Libraries/Components/MapView/MapView.js +++ b/Libraries/Components/MapView/MapView.js @@ -175,6 +175,7 @@ var RCTMap = createReactIOSNativeComponentClass({ region: {diff: deepDiffer}, maxDelta: true, minDelta: true, + pins: true, legalLabelInsets: {diff: insetsDiffer}, } ), diff --git a/React/Views/RCTMap.h b/React/Views/RCTMap.h index a280da4918fbd2..8aa20206e9b2f7 100644 --- a/React/Views/RCTMap.h +++ b/React/Views/RCTMap.h @@ -23,6 +23,6 @@ extern const CGFloat RCTMapZoomBoundBuffer; @property (nonatomic, assign) CGFloat maxDelta; @property (nonatomic, assign) UIEdgeInsets legalLabelInsets; @property (nonatomic, strong) NSTimer *regionChangeObserveTimer; -@property (nonatomic, strong) NSArray *pins; +@property (nonatomic, copy) NSArray *pins; @end diff --git a/React/Views/RCTMap.m b/React/Views/RCTMap.m index 72c0db5eb6e09e..f79ce162de6b78 100644 --- a/React/Views/RCTMap.m +++ b/React/Views/RCTMap.m @@ -21,6 +21,7 @@ @implementation RCTMap { UIView *_legalLabel; + NSArray *_pins; CLLocationManager *_locationManager; } @@ -39,6 +40,14 @@ - (instancetype)init return self; } +- (void)setPins:(NSArray *)pins +{ + if (_pins != pins) { + _pins = [pins copy]; + [self setNeedsLayout]; + } +} + - (void)dealloc { [_regionChangeObserveTimer invalidate]; diff --git a/React/Views/RCTMapManager.m b/React/Views/RCTMapManager.m index 186cb1ca75cc3c..dad8e633577a23 100644 --- a/React/Views/RCTMapManager.m +++ b/React/Views/RCTMapManager.m @@ -91,7 +91,6 @@ - (void)mapView:(RCTMap *)mapView didUpdateUserLocation:(MKUserLocation *)locati - (void)mapView:(RCTMap *)mapView regionWillChangeAnimated:(BOOL)animated { //Supported types: http://facebook.github.io/react-native/docs/nativemodulesios.html#argument-types - NSLog(@"It's me2: %@", _pins); [self _regionChanged:mapView]; mapView.regionChangeObserveTimer = [NSTimer timerWithTimeInterval:RCTMapRegionChangeObserveInterval From c405fc0c082a6eb25224dc63ac7fd8aadecbf3d9 Mon Sep 17 00:00:00 2001 From: Daniel Schmidt Date: Tue, 31 Mar 2015 14:39:56 +0200 Subject: [PATCH 4/6] added pins to map --- React/Views/RCTMap.m | 16 ++++++++-------- React/Views/RCTMapManager.m | 19 +++++++++++++++++-- 2 files changed, 25 insertions(+), 10 deletions(-) diff --git a/React/Views/RCTMap.m b/React/Views/RCTMap.m index f79ce162de6b78..e5324446de80ae 100644 --- a/React/Views/RCTMap.m +++ b/React/Views/RCTMap.m @@ -40,14 +40,6 @@ - (instancetype)init return self; } -- (void)setPins:(NSArray *)pins -{ - if (_pins != pins) { - _pins = [pins copy]; - [self setNeedsLayout]; - } -} - - (void)dealloc { [_regionChangeObserveTimer invalidate]; @@ -118,4 +110,12 @@ - (void)setRegion:(MKCoordinateRegion)region [super setRegion:region animated:YES]; } +- (void)setPins:(NSArray *)pins +{ + if (_pins != pins) { + _pins = [pins copy]; + [self setNeedsLayout]; + } +} + @end diff --git a/React/Views/RCTMapManager.m b/React/Views/RCTMapManager.m index dad8e633577a23..79db345b6a6c6f 100644 --- a/React/Views/RCTMapManager.m +++ b/React/Views/RCTMapManager.m @@ -90,7 +90,6 @@ - (void)mapView:(RCTMap *)mapView didUpdateUserLocation:(MKUserLocation *)locati - (void)mapView:(RCTMap *)mapView regionWillChangeAnimated:(BOOL)animated { - //Supported types: http://facebook.github.io/react-native/docs/nativemodulesios.html#argument-types [self _regionChanged:mapView]; mapView.regionChangeObserveTimer = [NSTimer timerWithTimeInterval:RCTMapRegionChangeObserveInterval @@ -100,7 +99,6 @@ - (void)mapView:(RCTMap *)mapView regionWillChangeAnimated:(BOOL)animated repeats:YES]; [[NSRunLoop mainRunLoop] addTimer:mapView.regionChangeObserveTimer forMode:NSRunLoopCommonModes]; - // TODO: Add pins here (http://www.appcoda.com/ios-programming-101-drop-a-pin-on-map-with-mapkit-api/) } - (void)mapView:(RCTMap *)mapView regionDidChangeAnimated:(BOOL)animated @@ -110,10 +108,27 @@ - (void)mapView:(RCTMap *)mapView regionDidChangeAnimated:(BOOL)animated [self _regionChanged:mapView]; [self _emitRegionChangeEvent:mapView continuous:NO]; + + for (NSDictionary *pin in mapView.pins) { + [self _addPin:pin ToMapView:mapView]; + } } #pragma mark Private +- (void)_addPin:(NSDictionary *)pinObject ToMapView:(RCTMap *)mapView +{ + MKPointAnnotation *pin = [[MKPointAnnotation alloc] init]; + CLLocationCoordinate2D coords; + coords.latitude = [[pinObject valueForKey:@"latitude"] doubleValue]; + coords.longitude = [[pinObject valueForKey:@"longitude"] doubleValue]; + pin.coordinate = coords; + + pin.title = [pinObject valueForKey:@"title"]; + pin.subtitle = [pinObject valueForKey:@"subtitle"]; + [mapView addAnnotation:pin]; +} + - (void)_onTick:(NSTimer *)timer { [self _regionChanged:timer.userInfo[@"mapView"]]; From 0f937c801b4439378f850493df207b0fc952c070 Mon Sep 17 00:00:00 2001 From: Daniel Schmidt Date: Wed, 15 Apr 2015 17:30:13 -0400 Subject: [PATCH 5/6] put the adding of the pins to the right place and therefore prevented the crashes --- React/Views/RCTMap.m | 21 +++++++++++++++++++++ React/Views/RCTMapManager.m | 18 ------------------ 2 files changed, 21 insertions(+), 18 deletions(-) diff --git a/React/Views/RCTMap.m b/React/Views/RCTMap.m index e5324446de80ae..65635923796cb0 100644 --- a/React/Views/RCTMap.m +++ b/React/Views/RCTMap.m @@ -70,6 +70,12 @@ - (void)layoutSubviews _legalLabel.frame = frame; }); } + + if (_pins) { + for (NSDictionary *pin in _pins) { + [self _addPin:pin ToMapView:self]; + } + } } #pragma mark Accessors @@ -118,4 +124,19 @@ - (void)setPins:(NSArray *)pins } } +#pragma mark Private + +- (void)_addPin:(NSDictionary *)pinObject ToMapView:(RCTMap *)mapView +{ + MKPointAnnotation *pin = [[MKPointAnnotation alloc] init]; + CLLocationCoordinate2D coords; + coords.latitude = [[pinObject valueForKey:@"latitude"] doubleValue]; + coords.longitude = [[pinObject valueForKey:@"longitude"] doubleValue]; + pin.coordinate = coords; + + pin.title = [pinObject valueForKey:@"title"]; + pin.subtitle = [pinObject valueForKey:@"subtitle"]; + [mapView addAnnotation:pin]; +} + @end diff --git a/React/Views/RCTMapManager.m b/React/Views/RCTMapManager.m index 79db345b6a6c6f..4eb6f88216ae3f 100644 --- a/React/Views/RCTMapManager.m +++ b/React/Views/RCTMapManager.m @@ -108,27 +108,9 @@ - (void)mapView:(RCTMap *)mapView regionDidChangeAnimated:(BOOL)animated [self _regionChanged:mapView]; [self _emitRegionChangeEvent:mapView continuous:NO]; - - for (NSDictionary *pin in mapView.pins) { - [self _addPin:pin ToMapView:mapView]; - } } #pragma mark Private - -- (void)_addPin:(NSDictionary *)pinObject ToMapView:(RCTMap *)mapView -{ - MKPointAnnotation *pin = [[MKPointAnnotation alloc] init]; - CLLocationCoordinate2D coords; - coords.latitude = [[pinObject valueForKey:@"latitude"] doubleValue]; - coords.longitude = [[pinObject valueForKey:@"longitude"] doubleValue]; - pin.coordinate = coords; - - pin.title = [pinObject valueForKey:@"title"]; - pin.subtitle = [pinObject valueForKey:@"subtitle"]; - [mapView addAnnotation:pin]; -} - - (void)_onTick:(NSTimer *)timer { [self _regionChanged:timer.userInfo[@"mapView"]]; From b9c241f25b2f0ff230d39cd0b1c8fc789a4ffcae Mon Sep 17 00:00:00 2001 From: Daniel Schmidt Date: Wed, 15 Apr 2015 17:54:28 -0400 Subject: [PATCH 6/6] fixed wsp and added pins to example --- Examples/UIExplorer/MapViewExample.js | 22 ++++++++++++++++++++++ React/Views/RCTMapManager.m | 2 ++ 2 files changed, 24 insertions(+) diff --git a/Examples/UIExplorer/MapViewExample.js b/Examples/UIExplorer/MapViewExample.js index ab6bd0717d8ec4..c9d5948d248de2 100644 --- a/Examples/UIExplorer/MapViewExample.js +++ b/Examples/UIExplorer/MapViewExample.js @@ -153,6 +153,7 @@ var MapViewExample = React.createClass({ mapRegionInput: null, annotations: null, isFirstLoad: true, + pins: null, }; }, @@ -165,6 +166,7 @@ var MapViewExample = React.createClass({ onRegionChangeComplete={this._onRegionChangeComplete} region={this.state.mapRegion} annotations={this.state.annotations} + pins={this.state.pins} /> = 0; i--) { + pin = { + title: 'Pin number ' + i, + subtitle: 'My cool subtitle', + latitude: region.latitude + (region.latitudeDelta * Math.random() * 2 - region.latitudeDelta), + longitude: region.longitude + (region.longitudeDelta * Math.random() * 2 - region.longitudeDelta) + }; + + arr.push(pin); + }; + + return arr; + }, + _getAnnotations(region) { return [{ longitude: region.longitude, @@ -193,6 +213,7 @@ var MapViewExample = React.createClass({ this.setState({ mapRegionInput: region, annotations: this._getAnnotations(region), + pins: this._getPins(region), isFirstLoad: false, }); } @@ -203,6 +224,7 @@ var MapViewExample = React.createClass({ mapRegion: region, mapRegionInput: region, annotations: this._getAnnotations(region), + pins: this._getPins(region), }); }, diff --git a/React/Views/RCTMapManager.m b/React/Views/RCTMapManager.m index bb299815a3f7c2..41641e2721e42f 100644 --- a/React/Views/RCTMapManager.m +++ b/React/Views/RCTMapManager.m @@ -45,6 +45,7 @@ - (UIView *)view RCT_EXPORT_VIEW_PROPERTY(pins, NSDictionaryArray) RCT_EXPORT_VIEW_PROPERTY(annotations, MKShapeArray) + #pragma mark MKMapViewDelegate - (void)mapView:(RCTMap *)mapView didUpdateUserLocation:(MKUserLocation *)location @@ -97,6 +98,7 @@ - (void)mapViewWillStartLoadingMap:(RCTMap *)mapView } #pragma mark Private + - (void)_onTick:(NSTimer *)timer { [self _regionChanged:timer.userInfo[RCTMapViewKey]];