Updated iOS native UI component events documentation
Summary: Documentation on iOS about triggering events from native components was outdated. Let me know what you think. Closes https://github.com/facebook/react-native/pull/6739 Differential Revision: D3240665 Pulled By: mkonicek fb-gh-sync-id: f62d52bebd58aae6f93388734338ef74ae536ec5 fbshipit-source-id: f62d52bebd58aae6f93388734338ef74ae536ec5
This commit is contained in:
parent
f99786cc89
commit
0045e07928
|
@ -223,7 +223,31 @@ var RCTSwitch = requireNativeComponent('RCTSwitch', Switch, {
|
|||
|
||||
## Events
|
||||
|
||||
So now we have a native map component that we can control easily from JS, but how do we deal with events from the user, like pinch-zooms or panning to change the visible region? The key is to make the `RCTMapManager` a delegate for all the views it vends, and forward the events to JS via the event dispatcher. This looks like so (simplified from the full implementation):
|
||||
So now we have a native map component that we can control easily from JS, but how do we deal with events from the user, like pinch-zooms or panning to change the visible region? The key is to declare an event handler property on `RCTMapManager`, make it a delegate for all the views it vends, and forward events to JS by calling the event handler block from the native view. This looks like so (simplified from the full implementation):
|
||||
|
||||
```objective-c
|
||||
// RCTMap.h
|
||||
|
||||
#import <MapKit/MapKit.h>
|
||||
|
||||
#import "RCTComponent.h"
|
||||
|
||||
@interface RCTMap: MKMapView
|
||||
|
||||
@property (nonatomic, copy) RCTBubblingEventBlock onChange;
|
||||
|
||||
@end
|
||||
```
|
||||
|
||||
```objective-c
|
||||
// RCTMap.m
|
||||
|
||||
#import "RCTMap.h"
|
||||
|
||||
@implementation RCTMap
|
||||
|
||||
@end
|
||||
```
|
||||
|
||||
```objective-c
|
||||
// RCTMapManager.m
|
||||
|
@ -232,8 +256,7 @@ So now we have a native map component that we can control easily from JS, but ho
|
|||
|
||||
#import <MapKit/MapKit.h>
|
||||
|
||||
#import "RCTBridge.h"
|
||||
#import "RCTEventDispatcher.h"
|
||||
#import "RCTMap.h"
|
||||
#import "UIView+React.h"
|
||||
|
||||
@interface RCTMapManager() <MKMapViewDelegate>
|
||||
|
@ -243,9 +266,11 @@ So now we have a native map component that we can control easily from JS, but ho
|
|||
|
||||
RCT_EXPORT_MODULE()
|
||||
|
||||
RCT_EXPORT_VIEW_PROPERTY(onChange, RCTBubblingEventBlock)
|
||||
|
||||
- (UIView *)view
|
||||
{
|
||||
MKMapView *map = [[MKMapView alloc] init];
|
||||
RCTMap *map = [RCTMap new];
|
||||
map.delegate = self;
|
||||
return map;
|
||||
}
|
||||
|
@ -254,21 +279,23 @@ RCT_EXPORT_MODULE()
|
|||
|
||||
- (void)mapView:(RCTMap *)mapView regionDidChangeAnimated:(BOOL)animated
|
||||
{
|
||||
if (!mapView.onChange) {
|
||||
return;
|
||||
}
|
||||
|
||||
MKCoordinateRegion region = mapView.region;
|
||||
NSDictionary *event = @{
|
||||
@"target": mapView.reactTag,
|
||||
mapView.onChange(@{
|
||||
@"region": @{
|
||||
@"latitude": @(region.center.latitude),
|
||||
@"longitude": @(region.center.longitude),
|
||||
@"latitudeDelta": @(region.span.latitudeDelta),
|
||||
@"longitudeDelta": @(region.span.longitudeDelta),
|
||||
}
|
||||
};
|
||||
[self.bridge.eventDispatcher sendInputEventWithName:@"topChange" body:event];
|
||||
});
|
||||
}
|
||||
```
|
||||
|
||||
You can see we're setting the manager as the delegate for every view that it vends, then in the delegate method `-mapView:regionDidChangeAnimated:` the region is combined with the `reactTag` target to make an event that is dispatched to the corresponding React component instance in your application via `sendInputEventWithName:body:`. The event name `@"topChange"` maps to the `onChange` callback prop in JavaScript. This callback is invoked with the raw event, which we typically process in the wrapper component to make a simpler API:
|
||||
You can see we're adding an event handler property to the view by subclassing `MKMapView`. Then we're exposing the `onChange` event handler property and setting the manager as the delegate for every view that it vends. Finally, in the delegate method `-mapView:regionDidChangeAnimated:` the event handler block is called on the corresponding view with the region data. Calling the `onChange` event handler block results in calling the same callback prop in JavaScript. This callback is invoked with the raw event, which we typically process in the wrapper component to make a simpler API:
|
||||
|
||||
```javascript
|
||||
// MapView.js
|
||||
|
|
Loading…
Reference in New Issue