I’m using the latest version of Expo Camera in my expo react native project and recently the camera has just been performing much worse than before. I’ve tried recreating the issue here:
import React, { useState, useRef } from 'react';
import { View, StyleSheet, Text, TouchableOpacity } from 'react-native';
import { CameraView, useCameraPermissions } from 'expo-camera';
import { useRoute } from '@react-navigation/native';
export default function CameraScreen() {
const [hasPermission, requestPermission] = useCameraPermissions();
const [isRecording, setIsRecording] = useState(false);
const [cameraRef, setCameraRef] = useState(null);
const [msg, setMsg] = useState('')
const isVideo = false
// const route = useRoute();
// const { page, photoID, id, isVideo } = route.params || {};
const handleCapture = async () => {
if (cameraRef) {
if (isVideo) {
if (isRecording) {
setIsRecording(false);
// Stop recording without expecting a return value
await cameraRef.stopRecording();
console.log('Stopped recording.');
setMsg('Stopped recording.')
} else {
console.log('Recording video...');
setMsg('Recording video...')
setIsRecording(true);
try {
// Start recording and get the video data
const videoData = await cameraRef.recordAsync();
console.log('Video recorded:', videoData.uri);
setMsg('Video recorded: ', videoData.uri)
} catch (error) {
setMsg('Error recording video:', error)
console.error('Error recording video:', error);
}
}
} else {
try {
const photoData = await cameraRef.takePictureAsync();
console.log('Photo taken:', photoData.uri);
setMsg('Photo taken: ', photoData.url)
} catch (error) {
setMsg('Error taking photo: ', error)
console.error('Error taking photo:', error);
}
}
}
};
if (!hasPermission) {
// Permissions are still loading or not granted
return (
<View style={styles.container}>
<Text>We need your permission to show the camera</Text>
<TouchableOpacity onPress={requestPermission}>
<Text>Grant Permission</Text>
</TouchableOpacity>
</View>
);
}
return (
<View style={styles.container}>
<CameraView
style={styles.camera}
facing={'back'}
ref={ref => setCameraRef(ref)}
mode={isVideo ? 'video' : 'picture'}
\>
<View style={styles.buttonContainer}>
<Text>{msg}</Text>
<TouchableOpacity style={styles.button} onPress={handleCapture}>
<Text style={styles.text}>
{isVideo ? (isRecording ? 'Stop Recording' : 'Record Video') : 'Take Photo'}
</Text>
</TouchableOpacity>
</View>
</CameraView>
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
backgroundColor: '#000',
},
camera: {
flex: 1,
},
buttonContainer: {
flex: 1,
backgroundColor: 'transparent',
justifyContent: 'flex-end',
},
button: {
alignSelf: 'center',
backgroundColor: 'white',
padding: 10,
borderRadius: 5,
marginBottom: 20,
},
text: {
fontSize: 18,
color: '#000',
},
});
My camera page will just randomly become unresponsive when I navigate to it for no reason. The only fix is to navigate back and reopen the page until the buttons work again. This happens across both apps I’ve developed.
I’ve tried twice to just recreate the page, each time with less features, but it’s always the same result. Whether it’s a photo or a video does not matter. 50% of the time the button will work and will record a video or capture a photo, the other 50% of the time, the buttons are completely unresponsive. In my first and second attempts at the camera page, I had a TouchableWithoutFeedback, like this:
<TouchableWithoutFeedback style={styles.focusableCameraArea} onPress={handleTapFocus}>
<View style={styles.focusableCameraArea} />
</TouchableWithoutFeedback>
where the handleTapFocus would log ‘tapped’ to the console (and show up as text on the screen when testing my native iOS build). Whenever the page was unresponsive, it wasn’t just the record button, but also my flip camera button, flash, and this touchable feedback that all just would not respond or give any feedback.
Note: The issue did not occur inside Expo or in my development build. Only after I built the app for iOS using EAS and submitted to Testflight to download did this issue occur. Also occurs in my other iOS app that’s on the App Store.