JakobGlieder
JakobGlieder

Reputation: 83

Image Picker using Camera in Landscape not working properly (SwiftUI)

My Image Picker does work with the Photo library in both orientations, but using the camera it doesn't adjust correctly to landscape.

This is how it looks: Landscape: Problematic Camera View Portrait: Camera View That Looks Normal

Here is My Code:

File1, UIViewControllerRepresentable:

import UIKit
import SwiftUI

struct ImagePicker: UIViewControllerRepresentable {

var sourceType: UIImagePickerController.SourceType = .photoLibrary

@Binding var selectedImage: UIImage
@Environment(\.presentationMode) private var presentationMode

func makeUIViewController(context: UIViewControllerRepresentableContext<ImagePicker>) -> UIImagePickerController {
    
    let imagePicker = UIImagePickerController()
    imagePicker.allowsEditing = true
    imagePicker.sourceType = sourceType
    imagePicker.delegate = context.coordinator
    
    return imagePicker
}

func updateUIViewController(_ uiViewController: UIImagePickerController, context: UIViewControllerRepresentableContext<ImagePicker>) {
    
}

func makeCoordinator() -> Coordinator {
    Coordinator(self)
}



final class Coordinator: NSObject, UIImagePickerControllerDelegate, UINavigationControllerDelegate {
    
    
    var parent: ImagePicker
    
    init(_ parent: ImagePicker) {
        self.parent = parent
    }
    
    func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
        
        if let image = info[UIImagePickerController.InfoKey.originalImage] as? UIImage {
            parent.selectedImage = image
        }
        
        parent.presentationMode.wrappedValue.dismiss()
    }
}
}

File 2, Using It:

.fullScreenCover(isPresented: $isShowPhotoLibrary) {
            ImagePicker(sourceType: .camera, selectedImage: self.$image)
        }

I am not fixed on using a fullScreenCover, just did that because it worked at least partially.

If anyone could help I would appreciate it a lot.

Upvotes: 5

Views: 922

Answers (2)

Malek Saadeh
Malek Saadeh

Reputation: 1

The way to go about this is to create a specific view that calls your ImagePicker, and lock that view in portrait mode.

First, in the AppDelegate, add this, which I learned from this video: https://www.youtube.com/watch?v=NNY6C9-QWCI

   static var orientationLock = UIInterfaceOrientationMask.all
    
    func application(_ application: UIApplication, supportedInterfaceOrientationsFor window: UIWindow?) -> UIInterfaceOrientationMask {
        return AppDelegate.orientationLock
    }

Then, make the view, ImagePickerView for example


import SwiftUI

struct ImagePickerView: View {
    
    @State private var image = UIImage()
  
    var body: some View {
        ZStack {
            ImagePicker(sourceType: .camera, selectedImage: $image)
        }
        .onAppear() {
            UIDevice.current.setValue(UIInterfaceOrientation.portrait.rawValue, forKey: "orientation")
            AppDelegate.orientationLock = .portrait
        }
        .onDisappear() {
            AppDelegate.orientationLock = .all
        }
    }
        
}

struct ImagePickerView_Previews: PreviewProvider {
    static var previews: some View {
        ImagePickerView()
    }
}

and to call the ImagePicker/camera from another view, just call ImagePickerView() and it should work well

Upvotes: 0

there maybe a workaround solution, but according to the Apple docs:

"The UIImagePickerController class supports portrait mode only. ...."

https://developer.apple.com/documentation/uikit/uiimagepickercontroller

Maybe you could use:

let theCamera = AVCaptureDevice.default(for: .video)

This works quite well.

Upvotes: 1

Related Questions