Fix Android ViewShot dropping frames and date overlays by temporarily lifting pointerEvents=none during capture

This commit is contained in:
2026-06-01 10:39:06 +02:00
parent 50df853ca8
commit 0a46baaa9b
2 changed files with 13 additions and 4 deletions
+3 -2
View File
@@ -3,6 +3,7 @@ import { StyleSheet, Image, View } from 'react-native';
interface FrameOverlayProps {
frameAsset: any; // require() asset
isCapturing?: boolean;
}
/**
@@ -10,11 +11,11 @@ interface FrameOverlayProps {
* The frame PNG must have a transparent center (alpha=0) so the photo shows through.
* Positioned absolutely to cover the entire photo canvas.
*/
export default function FrameOverlay({ frameAsset }: FrameOverlayProps) {
export default function FrameOverlay({ frameAsset, isCapturing = false }: FrameOverlayProps) {
if (!frameAsset) return null;
return (
<View style={styles.container} pointerEvents="none" collapsable={false}>
<View style={styles.container} pointerEvents={isCapturing ? "auto" : "none"} collapsable={false}>
<Image
source={frameAsset}
style={styles.frameImage}
+10 -2
View File
@@ -64,6 +64,7 @@ export default function PreviewScreen({
}: PreviewScreenProps) {
const [layout, setLayout] = useState<CollageLayout>('single');
const [isProcessing, setIsProcessing] = useState<boolean>(false);
const [isCapturing, setIsCapturing] = useState<boolean>(false);
const [statusMessage, setStatusMessage] = useState<string>('');
@@ -204,14 +205,21 @@ export default function PreviewScreen({
try {
logger.log(`captureComposite started. Has ViewShot ref: ${!!viewShotRef.current}`);
if (viewShotRef.current) {
setIsCapturing(true);
// Wait for React to re-render and remove pointerEvents="none" which blocks ViewShot on Android
await new Promise(resolve => setTimeout(resolve, 300));
logger.log('Executing viewShotRef.current.capture()...');
const uri = await viewShotRef.current.capture();
setIsCapturing(false);
logger.log(`ViewShot successfully generated collage URI: ${uri}`);
return uri;
}
logger.log('[WARNING] viewShotRef.current was null, falling back to raw photo.');
return fallbackPhoto;
} catch (e: any) {
setIsCapturing(false);
logger.error('Failed to capture composite (ViewShot crashed)', e?.message || e);
return fallbackPhoto;
}
@@ -453,11 +461,11 @@ export default function PreviewScreen({
{renderCollageView()}
{/* Frame Overlay */}
{activeFrame && <FrameOverlay frameAsset={activeFrame.asset} />}
{activeFrame && <FrameOverlay frameAsset={activeFrame.asset} isCapturing={isCapturing} />}
{/* Date/Time Overlay */}
{dateOverlay !== 'off' && (
<View style={[styles.dateOverlay, getDatePositionStyle()]} pointerEvents="none">
<View style={[styles.dateOverlay, getDatePositionStyle()]} pointerEvents={isCapturing ? "auto" : "none"}>
<Text style={styles.dateOverlayText}>
{formatDate(dateOverlay)}
</Text>