I've implemented a simple camera view:
import SwiftUI
import AVFoundation
struct CameraView: View {
@StateObject var model = CameraModel()
var body: some View {
CameraPreview(camera: model).ignoresSafeArea().onAppear() {
model.check()
}
}
}
struct CameraPreview: UIViewRepresentable {
@ObservedObject var camera: CameraModel
func makeUIView(context: Context) -> some UIView {
let view = UIView(frame: UIScreen.main.bounds)
camera.preview = AVCaptureVideoPreviewLayer(session: camera.session)
camera.preview.frame = view.frame
camera.preview.videoGravity = AVLayerVideoGravity.resizeAspectFill
view.layer.addSublayer(camera.preview)
camera.session.startRunning()
return view
}
func updateUIView(_ uiView: UIViewType, context: Context) {
}
}
struct CameraView_Previews: PreviewProvider {
static var previews: some View {
CameraView()
}
}
class CameraModel: ObservableObject {
@Published var session = AVCaptureSession()
@Published var alert = false
@Published var preview: AVCaptureVideoPreviewLayer!
func check() {
switch AVCaptureDevice.authorizationStatus(for: .video) {
case .authorized:
setUp()
break
case .notDetermined:
AVCaptureDevice.requestAccess(for: .video) { (status) in
if status {
self.setUp()
}
}
break
case .denied:
self.alert.toggle()
break
default:
break
}
}
func setUp() {
do {
self.session.beginConfiguration()
let device = AVCaptureDevice.default(.builtInDualCamera, for: .video, position: .back)
let input = try AVCaptureDeviceInput(device: device!)
if self.session.canAddInput(input) {
self.session.addInput(input)
}
self.session.commitConfiguration()
}
catch {
print(error.localizedDescription)
}
}
}
And show it as a tab in TabView
(root layer):
import SwiftUI
struct ContentView: View {
var body: some View {
TabView {
HomeView()
.tabItem {
Image("HomeIcon").renderingMode(.template)
Text("Home")
}
CameraView()
.tabItem {
Image("MapMarkerRadiusIcon").renderingMode(.template)
Text("Camera")
}
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
Unfortunately, CameraView()
overlays the bottom tab bar:
Looks okay? Unfortunately, no... It shows unselected icons when I am making a screenshot or going to hide app. When app is just launched and Camera
tab is opened, it looks as below:
How to fix this bug? I need to the tab bar was on the top always (like on the first screenshot)