Fix camera preview not rotating with device orientation
The preview layer's connection needs its own rotation update, separate from the capture output connections. Changes: - CameraPreviewUIView now listens to UIDevice.orientationDidChangeNotification - updatePreviewOrientation() updates the preview layer's connection - Called on layoutSubviews and orientation changes - Handles faceUp/faceDown/unknown by keeping current orientation - Uses modern videoRotationAngle API (iOS 17+)
This commit is contained in:
parent
0f2655593f
commit
80976c61d1
@ -104,12 +104,24 @@ class CameraPreviewUIView: UIView {
|
||||
backgroundColor = .black
|
||||
autoresizingMask = [.flexibleWidth, .flexibleHeight]
|
||||
setupPreviewLayer()
|
||||
|
||||
// Listen for orientation changes
|
||||
NotificationCenter.default.addObserver(
|
||||
self,
|
||||
selector: #selector(handleOrientationChange),
|
||||
name: UIDevice.orientationDidChangeNotification,
|
||||
object: nil
|
||||
)
|
||||
}
|
||||
|
||||
required init?(coder: NSCoder) {
|
||||
fatalError("init(coder:) has not been implemented")
|
||||
}
|
||||
|
||||
deinit {
|
||||
NotificationCenter.default.removeObserver(self)
|
||||
}
|
||||
|
||||
private func setupPreviewLayer() {
|
||||
guard let viewModel = viewModel,
|
||||
let session = viewModel.captureSession else { return }
|
||||
@ -119,6 +131,9 @@ class CameraPreviewUIView: UIView {
|
||||
layer.videoGravity = .resizeAspectFill
|
||||
previewLayer = layer
|
||||
viewModel.previewLayer = layer
|
||||
|
||||
// Set initial orientation
|
||||
updatePreviewOrientation()
|
||||
}
|
||||
}
|
||||
|
||||
@ -131,5 +146,42 @@ class CameraPreviewUIView: UIView {
|
||||
if previewLayer == nil {
|
||||
setupPreviewLayer()
|
||||
}
|
||||
|
||||
// Update orientation on layout changes
|
||||
updatePreviewOrientation()
|
||||
}
|
||||
|
||||
@objc private func handleOrientationChange() {
|
||||
updatePreviewOrientation()
|
||||
}
|
||||
|
||||
private func updatePreviewOrientation() {
|
||||
guard let connection = previewLayer?.connection else { return }
|
||||
|
||||
// Get rotation angle based on device orientation
|
||||
let deviceOrientation = UIDevice.current.orientation
|
||||
|
||||
// Calculate rotation angle (in degrees) for the preview layer
|
||||
let rotationAngle: CGFloat
|
||||
switch deviceOrientation {
|
||||
case .portrait:
|
||||
rotationAngle = 90
|
||||
case .portraitUpsideDown:
|
||||
rotationAngle = 270
|
||||
case .landscapeLeft:
|
||||
rotationAngle = 180
|
||||
case .landscapeRight:
|
||||
rotationAngle = 0
|
||||
case .faceUp, .faceDown, .unknown:
|
||||
// Keep current orientation for flat/unknown positions
|
||||
return
|
||||
@unknown default:
|
||||
rotationAngle = 90 // Default to portrait
|
||||
}
|
||||
|
||||
// Use modern rotation angle API (iOS 17+)
|
||||
if connection.isVideoRotationAngleSupported(rotationAngle) {
|
||||
connection.videoRotationAngle = rotationAngle
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -160,6 +160,10 @@
|
||||
"comment" : "A label displayed above a section of the settings view related to light colors.",
|
||||
"isCommentAutoGenerated" : true
|
||||
},
|
||||
"Locked. Tap to unlock with Pro." : {
|
||||
"comment" : "A hint that appears when a user taps on a color preset button.",
|
||||
"isCommentAutoGenerated" : true
|
||||
},
|
||||
"No Watermarks • Ad-Free" : {
|
||||
"comment" : "Description of a benefit that comes with the Pro subscription.",
|
||||
"isCommentAutoGenerated" : true
|
||||
@ -176,10 +180,6 @@
|
||||
"comment" : "A button label that opens the device settings when tapped.",
|
||||
"isCommentAutoGenerated" : true
|
||||
},
|
||||
"Opens color picker. Premium feature." : {
|
||||
"comment" : "An accessibility hint for the custom color button, describing its function.",
|
||||
"isCommentAutoGenerated" : true
|
||||
},
|
||||
"Opens upgrade options" : {
|
||||
"comment" : "An accessibility hint for the \"Upgrade to Pro\" button that indicates it opens upgrade options.",
|
||||
"isCommentAutoGenerated" : true
|
||||
|
||||
Loading…
Reference in New Issue
Block a user