Skip to content

Instantly share code, notes, and snippets.

@mdb1
Created January 30, 2024 22:54
Show Gist options
  • Save mdb1/e7eb3b43942a8087a1c22ff1c59da733 to your computer and use it in GitHub Desktop.
Save mdb1/e7eb3b43942a8087a1c22ff1c59da733 to your computer and use it in GitHub Desktop.
A modifier that adds image selection capabilities to a view
import Foundation
import SwiftUI
struct ImageSelectorOptionsModifier: ViewModifier {
var title: String
var titleVisibility: Visibility
var galleryOptionTitle: String
var takePictureOptionTitle: String
@Binding var isPresentingSourceSelector: Bool
@Binding var selectedImage: UIImage?
@State private var isPresentingImagePickerOptions: Bool = false
@State private var sourceSelection: UIImagePickerController.SourceType?
func body(content: Content) -> some View {
content
.confirmationDialog(
title,
isPresented: $isPresentingSourceSelector,
titleVisibility: titleVisibility
) {
Button(galleryOptionTitle) {
sourceSelection = .photoLibrary
isPresentingImagePickerOptions = true
}
Button(takePictureOptionTitle) {
sourceSelection = .camera
isPresentingImagePickerOptions = true
}
#if targetEnvironment(simulator)
.disabled(true)
#endif
}
.sheet(isPresented: $isPresentingImagePickerOptions) {
if let source = sourceSelection {
ImagePicker(sourceType: source, selectedImage: $selectedImage)
}
}
}
}
extension View {
/// A modifier that adds image selection capabilities to a view.
/// Applying this modifier will let the view present a confirmation dialog with the given properties
/// to change an image, letting the users select an image from their gallery or with their camera.
/// - Parameters:
/// - title: The title of the confirmation dialog.
/// - titleVisibility: The visibility of the title.
/// - galleryOptionTitle: The text to display for the Gallery Source Option.
/// - takePictureOptionTitle: The text to display for the Camera Source Option.
/// - isPresentingSourceSelector: The binding to present the dialog.
/// - selectedImage: A binding to represent the image selected by the user.
/// - Usage:
/// To use this modifier, you need two @State properties in the View:
/// ```swift
/// @State private var isPresentingImagePickerOptions = false
/// @State private var selectedImage: UIImage?
/// ```
/// - Then: Just add the modifier using those properties:
/// ```swift
/// Button("Present Picker") {
/// isPresentingImagePickerOptions = true
/// }
/// .imageSelectorOptions(
/// title: "Select Source",
/// titleVisibility: .visible,
/// isPresentingSourceSelector: $isPresentingImagePickerOptions,
/// selectedImage: $selectedImage
/// )
/// ```
/// - Returns: The original view with the applied modifier.
func imageSelectorOptions(
title: String = "",
titleVisibility: Visibility = .automatic,
galleryOptionTitle: String = "Choose from gallery",
takePictureOptionTitle: String = "Take Picture",
isPresentingSourceSelector: Binding<Bool>,
selectedImage: Binding<UIImage?>
) -> some View {
self.modifier(
ImageSelectorOptionsModifier(
title: title,
titleVisibility: titleVisibility,
galleryOptionTitle: galleryOptionTitle,
takePictureOptionTitle: takePictureOptionTitle,
isPresentingSourceSelector: isPresentingSourceSelector,
selectedImage: selectedImage
)
)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment