SwiftUIでカメラ機能を実装する方法についてです。
基本機能の実装
import SwiftUI
import AVFoundation
struct CameraContentView: View {
var body: some View {
CameraView()
.edgesIgnoringSafeArea(.all)
}
}
struct CameraView: UIViewRepresentable {
func makeUIView(context: Context) -> UIView { BaseCameraView() }
func updateUIView(_ uiView: UIViewType, context: Context) {}
}
class BaseCameraView: UIView {
override func layoutSubviews() {
super.layoutSubviews()
_ = initCaptureSession
(layer.sublayers?.first as? AVCaptureVideoPreviewLayer)?.frame = bounds
}
lazy var initCaptureSession: Void = {
guard let device = AVCaptureDevice.DiscoverySession(deviceTypes: [.builtInWideAngleCamera],
mediaType: .video,
position: .unspecified)
.devices.first(where: { $0.position == .front }),
let input = try? AVCaptureDeviceInput(device: device) else { return }
let session = AVCaptureSession()
session.addInput(input)
session.startRunning()
layer.insertSublayer(AVCaptureVideoPreviewLayer(session: session), at: 0)
}()
}
このコードを実行すると、フロントカメラが起動し、画面全体に映像が表示されます。
画面の向きに合わせてカメラの向きを変える
このままだと、端末の向きを変えた時に縦:横=16:9の比率を保ったまま回転してしまうので、画面の向きに応じたカメラの映像が出てこなくなってしました。
そこで下記コードを追記しました。
enum Orientation: Int {
case right = -1, down = 0, left = 1, up = 2
}
private func getDeviceOrientation() -> Orientation {
guard let interfaceOrientation = UIApplication.shared.windows.first(where: { $0.isKeyWindow })?.windowScene?.interfaceOrientation else {
return .right
}
switch interfaceOrientation {
case .landscapeLeft:
return .left
case .landscapeRight:
return .right
case .portrait:
return .down
case .portraitUpsideDown:
return .up
default:
return .right
}
}
private func fixCameraOrientation() {
let rotation: CGFloat = CGFloat(getDeviceOrientation().rawValue) * 90
previewLayer?.transform = CATransform3DMakeRotation(rotation / 180 * CGFloat.pi, 0, 0, 1)
}
これらの関数をlayoutSubviews
に追加することで、デバイスの向きが変わるたびにカメラの向きも適切に調整されます。
参考文献様
以下の記事に助けられました感謝
コメントを残す