Skip to content

fix(ios): sync preview orientation with device orientation#86

Open
grfalk wants to merge 1 commit intoNativeScript:mainfrom
grfalk:fix/ios-preview-orientation-landscape
Open

fix(ios): sync preview orientation with device orientation#86
grfalk wants to merge 1 commit intoNativeScript:mainfrom
grfalk:fix/ios-preview-orientation-landscape

Conversation

@grfalk
Copy link
Copy Markdown

@grfalk grfalk commented Apr 5, 2026

Problem

The AVCaptureVideoPreviewLayer connection orientation is never synced with the current device orientation. This causes the camera preview to appear rotated 90 degrees when the device is in landscape mode - most commonly observed on iPad, but affects any iOS device that supports multiple orientations.

Root Cause

In index.ios.ts, createNativeView() creates the AVCaptureVideoPreviewLayer from the capture session and adds it to the view, but never sets videoOrientation (or videoRotationAngle on iOS 17+) on the layer connection. The onLayout() method updates the layer frame but not its orientation.

Fix

Added a private _syncPreviewOrientation() method that:

  1. Reads the current interface orientation from UIWindowScene.interfaceOrientation (the modern API, replacing the deprecated UIApplication.statusBarOrientation)
  2. Maps the UIInterfaceOrientation value to the appropriate rotation angle
  3. Applies the rotation via videoRotationAngle (iOS 17+) or falls back to the deprecated videoOrientation for older iOS versions
  4. Uses setTimeout to defer the update, as the AVCaptureConnection may not be established immediately after startPreview()

The method is called:

  • After startPreview() in onLoaded()
  • On Application.orientationChanged events (listener registered in onLoaded(), removed in onUnloaded())
  • After toggleCamera(), since switching cameras resets the session connection

Testing

Verified the fix corrects the 90-degree rotation on iPad in landscape mode when using MLKitView with DetectionType.Barcode via @nativescript/mlkit-barcode-scanning.

Made with Cursor

The AVCaptureVideoPreviewLayer connection orientation is never synced
with the device orientation, causing the camera preview to appear
rotated 90 degrees when the device is in landscape mode (e.g. iPad).

Add _syncPreviewOrientation() which reads the current interface
orientation from UIWindowScene and applies it to the preview layer
connection using videoRotationAngle (iOS 17+) or the deprecated
videoOrientation fallback. The sync is called on load, on orientation
change, and after toggleCamera().
@cla-bot
Copy link
Copy Markdown

cla-bot bot commented Apr 5, 2026

Thank you for your pull request and welcome to our community. We could not parse the GitHub identity of the following contributors: Gary Faulkner.
This is most likely caused by a git client misconfiguration; please make sure to:

  1. check if your git client is configured with an email to sign commits git config --list | grep email
  2. If not, set it up using git config --global user.email email@example.com
  3. Make sure that the git commit email is configured in your GitHub account settings, see https://github.com/settings/emails

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant