From bde72fc6cadaf7829595bb6f90311755e6804f08 Mon Sep 17 00:00:00 2001 From: Mike Subelsky <12020+subelsky@users.noreply.github.com> Date: Fri, 31 May 2024 12:01:20 -0400 Subject: [PATCH] Enhance orientation handling in InteractivePreview and Preview classes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Summary: Improved the handling of orientation changes in the `InteractivePreview` and `Preview` classes to ensure proper resizing and layout adjustments of the `AVCaptureVideoPreviewLayer` during device rotation. These changes address issues where the preview layer would not correctly adapt to new geometry sizes, leading to misalignment. Details: 1. `InteractivePreview`: - Added an `onChange` modifier to observe changes in the geometry size. - Updated the `layer` frame on the main dispatch queue to ensure proper resizing. 2. `Preview`: - Removed the direct assignment of `previewLayer.frame` in `updateUIViewController`. - Ensured the `previewLayer` is added to the view controller’s layer only if it hasn’t been added already. - Updated the `previewLayer.frame` on the main dispatch queue to ensure it resizes correctly when the view bounds change. NOTE: This will not affect the orientation of the session. To do that, application code must wrap the preview layer with handlers that call `aespaSession.common(.orientation(orientation: ...))`. I have some code that demonstrates this, but it's very specific to my app, so I couldn't cleanly extract a good example for the README. I can try to tackle that in a future commit. --- Sources/Aespa/View/InteractivePreview.swift | 5 +++++ Sources/Aespa/View/Preview.swift | 9 ++++++--- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/Sources/Aespa/View/InteractivePreview.swift b/Sources/Aespa/View/InteractivePreview.swift index 25071aa..df4b2a6 100644 --- a/Sources/Aespa/View/InteractivePreview.swift +++ b/Sources/Aespa/View/InteractivePreview.swift @@ -112,6 +112,11 @@ public struct InteractivePreview: View { .opacity(focusFrameOpacity) .animation(.spring(), value: focusFrameOpacity) } + .onChange(of: geometry.size) { newSize in + DispatchQueue.main.async { + layer.frame = CGRect(origin: .zero, size: newSize) + } + } } } } diff --git a/Sources/Aespa/View/Preview.swift b/Sources/Aespa/View/Preview.swift index 375d98f..22f13b3 100644 --- a/Sources/Aespa/View/Preview.swift +++ b/Sources/Aespa/View/Preview.swift @@ -32,9 +32,12 @@ struct Preview: UIViewControllerRepresentable { func updateUIViewController(_ uiViewController: UIViewController, context: Context) { previewLayer.videoGravity = gravity - uiViewController.view.layer.addSublayer(previewLayer) - - previewLayer.frame = uiViewController.view.bounds + if previewLayer.superlayer == nil { + uiViewController.view.layer.addSublayer(previewLayer) + } + DispatchQueue.main.async { + self.previewLayer.frame = uiViewController.view.bounds + } } func dismantleUIViewController(_ uiViewController: UIViewController, coordinator: ()) {