0
0
iOS Swiftmobile~20 mins

Camera and photo library in iOS Swift - Mini App: Build & Ship

Choose your learning style9 modes available
Build: PhotoPickerScreen
This screen lets users take a photo with the camera or pick one from the photo library. The chosen photo is shown on the screen.
Target UI
-------------------------
| Photo Picker          |
|-----------------------|
| [Take Photo] [Gallery]|
|                       |
|                       |
|       [ImageView]     |
|                       |
|                       |
-------------------------
Add two buttons side by side: 'Take Photo' and 'Gallery'.
When 'Take Photo' is tapped, open the camera to take a new photo.
When 'Gallery' is tapped, open the photo library to pick an existing photo.
Show the selected or taken photo below the buttons.
Handle permissions for camera and photo library access.
If the device has no camera, disable the 'Take Photo' button.
Starter Code
iOS Swift
import SwiftUI
import PhotosUI
import UIKit

struct PhotoPickerScreen: View {
    @State private var image: Image? = nil
    @State private var showCamera = false
    @State private var showPhotoLibrary = false

    var body: some View {
        VStack {
            HStack {
                Button("Take Photo") {
                    // TODO: Show camera
                }
                .disabled(!UIImagePickerController.isSourceTypeAvailable(.camera))

                Button("Gallery") {
                    // TODO: Show photo library
                }
            }
            .padding()

            Spacer()

            if let image = image {
                image
                    .resizable()
                    .scaledToFit()
                    .frame(maxWidth: 300, maxHeight: 300)
            } else {
                Text("No photo selected")
                    .foregroundColor(.gray)
            }

            Spacer()
        }
        .sheet(isPresented: $showCamera) {
            // TODO: Camera picker
        }
        .sheet(isPresented: $showPhotoLibrary) {
            // TODO: Photo library picker
        }
    }
}

struct PhotoPickerScreen_Previews: PreviewProvider {
    static var previews: some View {
        PhotoPickerScreen()
    }
}
Task 1
Task 2
Task 3
Task 4
Task 5
Solution
iOS Swift
import SwiftUI
import UIKit

struct PhotoPickerScreen: View {
    @State private var image: Image? = nil
    @State private var showCamera = false
    @State private var showPhotoLibrary = false
    @State private var inputImage: UIImage? = nil

    var body: some View {
        VStack {
            HStack {
                Button("Take Photo") {
                    showCamera = true
                }
                .disabled(!UIImagePickerController.isSourceTypeAvailable(.camera))
                .padding()

                Button("Gallery") {
                    showPhotoLibrary = true
                }
                .padding()
            }

            Spacer()

            if let image = image {
                image
                    .resizable()
                    .scaledToFit()
                    .frame(maxWidth: 300, maxHeight: 300)
            } else {
                Text("No photo selected")
                    .foregroundColor(.gray)
            }

            Spacer()
        }
        .sheet(isPresented: $showCamera) {
            ImagePicker(sourceType: .camera, selectedImage: $inputImage)
        }
        .sheet(isPresented: $showPhotoLibrary) {
            ImagePicker(sourceType: .photoLibrary, selectedImage: $inputImage)
        }
        .onChange(of: inputImage) { _ in loadImage() }
    }

    func loadImage() {
        guard let inputImage = inputImage else { return }
        image = Image(uiImage: inputImage)
    }
}

struct ImagePicker: UIViewControllerRepresentable {
    class Coordinator: NSObject, UINavigationControllerDelegate, UIImagePickerControllerDelegate {
        let parent: ImagePicker

        init(_ parent: ImagePicker) {
            self.parent = parent
        }

        func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
            if let uiImage = info[.originalImage] as? UIImage {
                parent.selectedImage = uiImage
            }
            picker.dismiss(animated: true)
        }

        func imagePickerControllerDidCancel(_ picker: UIImagePickerController) {
            picker.dismiss(animated: true)
        }
    }

    var sourceType: UIImagePickerController.SourceType
    @Binding var selectedImage: UIImage?

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

    func makeUIViewController(context: Context) -> UIImagePickerController {
        let picker = UIImagePickerController()
        picker.delegate = context.coordinator
        picker.sourceType = sourceType
        return picker
    }

    func updateUIViewController(_ uiViewController: UIImagePickerController, context: Context) {}
}

struct PhotoPickerScreen_Previews: PreviewProvider {
    static var previews: some View {
        PhotoPickerScreen()
    }
}

This solution uses SwiftUI with a UIViewControllerRepresentable wrapper called ImagePicker to access the camera and photo library.

Two buttons let the user choose between taking a photo or picking from the gallery. The 'Take Photo' button is disabled if the device has no camera.

When a photo is selected or taken, it updates the inputImage state, which triggers loadImage() to convert it to a SwiftUI Image and display it.

The ImagePicker uses UIKit's UIImagePickerController to handle the camera and photo library, with a coordinator to manage delegate callbacks.

This approach handles permissions automatically by the system when accessing camera or photo library.

Final Result
Completed Screen
-------------------------
| Photo Picker          |
|-----------------------|
| [Take Photo] [Gallery]|
|                       |
|                       |
|     [Selected Image]  |
|                       |
|                       |
-------------------------
Tapping 'Take Photo' opens the camera to take a new picture.
Tapping 'Gallery' opens the photo library to pick an existing photo.
After selecting or taking a photo, the image appears below the buttons.
If the device has no camera, 'Take Photo' button is disabled.
Stretch Goal
Add a button to save the selected photo to the user's photo library.
💡 Hint
Use UIImageWriteToSavedPhotosAlbum to save the UIImage and show a confirmation alert.