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
|
backgroundColor = .black
|
||||||
autoresizingMask = [.flexibleWidth, .flexibleHeight]
|
autoresizingMask = [.flexibleWidth, .flexibleHeight]
|
||||||
setupPreviewLayer()
|
setupPreviewLayer()
|
||||||
|
|
||||||
|
// Listen for orientation changes
|
||||||
|
NotificationCenter.default.addObserver(
|
||||||
|
self,
|
||||||
|
selector: #selector(handleOrientationChange),
|
||||||
|
name: UIDevice.orientationDidChangeNotification,
|
||||||
|
object: nil
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
required init?(coder: NSCoder) {
|
required init?(coder: NSCoder) {
|
||||||
fatalError("init(coder:) has not been implemented")
|
fatalError("init(coder:) has not been implemented")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
deinit {
|
||||||
|
NotificationCenter.default.removeObserver(self)
|
||||||
|
}
|
||||||
|
|
||||||
private func setupPreviewLayer() {
|
private func setupPreviewLayer() {
|
||||||
guard let viewModel = viewModel,
|
guard let viewModel = viewModel,
|
||||||
let session = viewModel.captureSession else { return }
|
let session = viewModel.captureSession else { return }
|
||||||
@ -119,6 +131,9 @@ class CameraPreviewUIView: UIView {
|
|||||||
layer.videoGravity = .resizeAspectFill
|
layer.videoGravity = .resizeAspectFill
|
||||||
previewLayer = layer
|
previewLayer = layer
|
||||||
viewModel.previewLayer = layer
|
viewModel.previewLayer = layer
|
||||||
|
|
||||||
|
// Set initial orientation
|
||||||
|
updatePreviewOrientation()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -131,5 +146,42 @@ class CameraPreviewUIView: UIView {
|
|||||||
if previewLayer == nil {
|
if previewLayer == nil {
|
||||||
setupPreviewLayer()
|
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.",
|
"comment" : "A label displayed above a section of the settings view related to light colors.",
|
||||||
"isCommentAutoGenerated" : true
|
"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" : {
|
"No Watermarks • Ad-Free" : {
|
||||||
"comment" : "Description of a benefit that comes with the Pro subscription.",
|
"comment" : "Description of a benefit that comes with the Pro subscription.",
|
||||||
"isCommentAutoGenerated" : true
|
"isCommentAutoGenerated" : true
|
||||||
@ -176,10 +180,6 @@
|
|||||||
"comment" : "A button label that opens the device settings when tapped.",
|
"comment" : "A button label that opens the device settings when tapped.",
|
||||||
"isCommentAutoGenerated" : true
|
"isCommentAutoGenerated" : true
|
||||||
},
|
},
|
||||||
"Opens color picker. Premium feature." : {
|
|
||||||
"comment" : "An accessibility hint for the custom color button, describing its function.",
|
|
||||||
"isCommentAutoGenerated" : true
|
|
||||||
},
|
|
||||||
"Opens upgrade options" : {
|
"Opens upgrade options" : {
|
||||||
"comment" : "An accessibility hint for the \"Upgrade to Pro\" button that indicates it opens upgrade options.",
|
"comment" : "An accessibility hint for the \"Upgrade to Pro\" button that indicates it opens upgrade options.",
|
||||||
"isCommentAutoGenerated" : true
|
"isCommentAutoGenerated" : true
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user