capacitor-community / capacitor-community/camera-preview
False Orientation Change when Tilting Device
- Dominant language
- Java
- Stars
- 227
- Forks
- 185
- PR merge metrics
- No merged PRs in 30d
Description
**Describe the bug**
When `rotateWhenOrientationChanged` is set to `true` on iOS, slightly tilting the device upward triggers an unintended orientation change and swaps frame dimensions, even though the device remains in portrait mode.
**To Reproduce**
Steps to reproduce the behavior:
1. Initialize the Preview Camera with `rotateWhenOrientationChanged = true` and custom coordinates (e.g., `{"x": 540, "y": 102, "width": 630, "height": 620}`).
2. Hold the iOS device in landscape orientation.
3. Tilt the device slightly upward towards a flat/horizontal angle.
4. Observe the preview frame shifting position incorrectly to swapped coordinates (e.g., `x: 51, y: 270`).
**Expected behavior**
The camera preview frame should remain locked to its assigned bounding box `(x, y, width, height)`. Upward tilting (`faceUp` state) should be ignored, and only actual physical orientation changes should update the video orientation connection without swapping parent layout coordinates.
**Screenshots**
https://github.com/user-attachments/assets/ed4d5219-0cc4-444e-b82d-fd990b4956a8
**Desktop (please complete the following information):**
N/A
**Smartphone (please complete the following information):**
- Device: Ipad
- OS: IPad OS 26.0
- Browser: N/A
- Version: N/A
**Additional context**
The issue is possible driven by two underlying implementation bugs in the iOS preview handling:
1. **Deprecated Status Check Misfiring:** The plugin evaluates `UIApplication.shared.statusBarOrientation`, which falls back or misfires when transitioning to a physical `faceUp` state during tilts. Device accelerometer/orientation plugins do not fire during this tilt, causing a state mismatch.
2. **Layout Axis Swapping:** When `.isLandscape` evaluates to true during a misfire, the Swift logic explicitly swaps origin coordinates and bounding dimensions:
```swift
previewView.frame = CGRect(x: y, y: x, width: max(adjustedHeight, width), height: min(adjustedHeight, width))
Contributor guide
Research direction
Start by tracing the iOS preview handling that reads UIApplication.shared.statusBarOrientation and applies the shown previewView.frame CGRect transformation. Reproduce the tilt toward faceUp with rotateWhenOrientationChanged enabled and verify that the assigned bounding box remains unchanged while genuine orientation changes still update the video orientation connection.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- ios, swift
- Domain
- mobile-dev
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 58/100