There are three steps to install react-native-camera and to include it in our CameraScreen
. From the command line, navigate to the ReactNotes
directory and run the following command:
npm install [email protected] --save
If you take a look at the node_modules
directory in the ReactNotes
project you'll see a new directory named react-native-camera
, which contains both the JavaScript and native source code of the module. In the ios
subdirectory, you'll notice a file called RCTCamera.xcodeproj
, as shown in the following screenshot:
We need to add this file to our Xcode project's library. In the Xcode project navigator, right-click on Libraries and choose Add Files to ReactNotes:
In the Finder window that appears, navigate to ReactNotes | node_modules | react-native-camera | ios, select RCTCamera.xcodeproj and click Add:
Take a look at the Libraries folder in the project navigator and you should see RCTCamera.xcodeproj in the list.
Next, select ReactNotes in the project navigator, click on Build Phases and expand the Link Binary With Libraries section:
Click the plus sign at the bottom of the Link Binary with Libraries section, select libRCTCamera.a from the list and click Add:
We're now ready to use the camera component in our application.
A brief note before we start using the camera component is how you can find these modules on your own. The two best places to look for open source Native Modules are either on GitHub (https://github.com) or NPM (https://www.npmjs.com). A search on either of these sites will give you plenty of third-party modules created by the React Native community to use in your projects.
The hard part is over! Importing the camera module is as simple as including any other React component:
import Camera from 'react-native-camera';
Using the Camera component is quite simple, as well. Here's the render
function of the CameraScreen
:
render () { return ( <Camera captureTarget={Camera.constants.CaptureTarget.disk} ref="cam" style={styles.container} > <View style={styles.cameraButtonContainer}> <SimpleButton onPress={this._takePicture.bind(this)} customText="Capture" style={styles.cameraButton} textStyle={styles.cameraButtonText} /> </View> </Camera> ); }
The Camera module exposes a number of props that you can use to customize its behavior but most of the default values work well for our purpose. However, you'll note that we set the captureTarget
property to Camera.constants.CaptureTarget.disk
. This setting will place the saved images into a directory on the device that only our ReactNotes
application has access to. The default value for the captureTarget
property is Camera.constants.CaptureTarget.cameraRoll
, which will put the image in the shared location used by the native camera when you're taking pictures. Although that will normally be acceptable, at the time of this writing there is a bug that prevents ReactNative from loading images from that location.
Take a look at the code listing above. Notice that we've added child components to the camera component. It behaves just like a View
component; you're now familiar with laying out children using the Flexbox
attribute. In our example, we've added a View
and a SimpleButton
with an onPress
handler that will capture the image:
_takePicture () { this.refs.cam.capture((err, data) => { if (err) return; this.props.onPicture(data); }); }
Recall that we added ref="cam"
to the camera component declaration; thus, allowing us to refer to it in our handler. When we call the capture()
function, we pass in a callback that takes two arguments, err
(which should be null unless the user doesn't permit ReactNotes
to use the camera) and data, which will include the full path to the image once it is saved to disk.
In order to save the path to the image along with the note, we'll need to pass the data up using this.props.onPicture(data)
. We'll need to update our top-level ReactNotes
component, but before we do that, here's the complete code for the CameraScreen
:
import React, { StyleSheet, Text, View } from 'react-native'; import Camera from 'react-native-camera'; import SimpleButton from './SimpleButton'; export default class CameraScreen extends React.Component { _takePicture () { this.refs.cam.capture((err, data) => { if (err) return; this.props.onPicture(data); }); } render () { return ( <Camera captureTarget={Camera.constants.CaptureTarget.disk} ref="cam" style={styles.container} > <View style={styles.cameraButtonContainer}> <SimpleButton onPress={this._takePicture.bind(this)} customText="Capture" style={styles.cameraButton} textStyle={styles.cameraButtonText} /> </View> </Camera> ); } } var styles = StyleSheet.create({ container: { flex: 1, marginTop: 64 }, cameraButtonContainer: { position: 'absolute', bottom: 20, left: 20, right: 20 }, cameraButton: { backgroundColor: '#5B29C1', borderRadius: 4, paddingHorizontal: 20, paddingVertical: 15 }, cameraButtonText: { color: 'white', textAlign: 'center' } });
Return to index.ios.js
and add the onPicture
callback to the CameraScreen
props:
renderScene(route, navigator) { switch (route.name) { case 'home': return ( … case 'camera': return ( <CameraScreen onPicture={(imagePath) => this.saveNoteImage(imagePath, route.note)}/> ); … } } }
We're passing in a callback that takes an imagePath
and then calls this.saveNoteImage(imagePath, route.note)
. Let's add that function just above renderScene
:
saveNoteImage(imagePath, note) { note.imagePath = imagePath; this.updateNote(note); }
This function simply takes the imagePath
, adds it to the note object, and passes the modified note to our updateNote()
function.
Now you can run the application in the simulator, click the Take Picture button and the screen becomes black! Don't worry, there's nothing wrong with your code; the iOS simulator doesn't have access to a camera, so it displays a black screen. However, if you click the Capture button, an image will be saved to your file system and when you return to view the image you'll actually see a white screen.
To verify if this works, you can console.log
the imagePath
, navigate to the image, modify the image, and then return to the NoteImageScreen
to see your changes.
3.143.4.181