Created
January 30, 2024 22:54
-
-
Save mdb1/e7eb3b43942a8087a1c22ff1c59da733 to your computer and use it in GitHub Desktop.
A modifier that adds image selection capabilities to a view
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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