frank
frank

Reputation: 1342

UIImagePickerController overlay view using React Native components

I want to define a UIImagePickerController overlay view using React Native components. I'm setting up to add a new option to Marc Shilling fabulous react-native-image-picker. I want the ImagePickerManager.launchCamera function to take a <View> and children as one of its parameters, render it, and pass that to UIImagePickerController.cameraOverlayView. I got this far:

In ImagePickerManager.m:

NSNumber *viewTag = [self.options valueForKey:@"overlayNode"];
if (![viewTag isEqual:[NSNull null]] && viewTag != 0) {
    UIView *view = [_bridge.uiManager viewForReactTag:viewTag];
    [self.picker setCameraOverlayView:view];
}

But this requires me to do some contortions on the JS side in order to get a component instance.

React.createClass({
    render: function() { 
        return (
            <View>
                <TouchableHighlight onPress={this._showCamera}><Text>Camera</Text></TouchableHighlight>
                <View ref="foo"><Text>On top of the camera!</Text></View>
            </View>
        );
    },
    _showCamera: function() {
        var options = {
            overlayNode: React.findNodeHandle(this.refs.foo),
        };
        ImagePickerManager.launchCamera(options, (response)  => {

        });
    }
});

I get a redbox if I try to say overlayNode: React.findNodeHandle(<View ref="foo"><Text>On top of the camera!</Text></View>).

I experimented a bit with creating a new RCTRootView and registering the overlay via AppRegistry.registerComponent but I didn't see anything actually render on the screen.

NSString *overlayRootName = [self.options valueForKey:@"overlayComponentName"];
if (![overlayRootName isEqual:[NSNull null]] && overlayRootName.length != 0) {
    RCTRootView *rootView = [[RCTRootView alloc] initWithBridge:self.bridge moduleName:overlayRootName initialProperties:nil];
    [self.picker setCameraOverlayView:rootView];
}

What am I missing here?

Upvotes: 2

Views: 1295

Answers (1)

frank
frank

Reputation: 1342

The latter solution (declaring an alternative RCTRootView) ended up being the one that worked for me. The problem I was having was that for some reason the bridge that I got in the ImagePickerManager from adding @synthesize bridge = _bridge; was not rendering anything when used in initWithBridge.

Instead, I added a field to my AppDelegate exposing the bridge created in application: didFinishLaunchingWithOptions: much like what was done in this hybrid app example. When I use that bridge in initWithBridge, the overlay renders on the screen. Also made sure to explicitly set rootView.frame and rootView.backgroundColor to transparent.

Screenshot of UIImagePicker with React Native Overlay

Upvotes: 1

Related Questions