I would like to display a PhotosUI
PhotosPicker
via a longPressGesture
of a UIImage
.
import SwiftUI
import PhotosUI
@MainActor
final class TestViewModelProfile: ObservableObject {
@Published private(set) var selectedImage: UIImage? = nil
@Published var imageSelection: PhotosPickerItem? = nil {
didSet {
setImage(from: imageSelection)
}
}
private func setImage(from selection: PhotosPickerItem?) {
guard let selection else { return }
Task {
if let data = try? await selection.loadTransferable(type: Data.self) {
if let uiImage = UIImage(data: data) {
selectedImage = uiImage
return
}
}
}
}
}
struct ProfilePageViewTest: View {
@State var profilePhoto: Image?
@StateObject private var viewModel = PhotoPickerViewModel()
var body: some View {
VStack {
if let image = viewModel.selectedImage {
Image(uiImage: image)
.resizable()
.aspectRatio(contentMode: .fill)
.frame(width: 100, height: 100)
.clipShape(Circle())
.gesture(
LongPressGesture(minimumDuration: 1.0)
.onEnded { _ in
// Perform image upload logic here
uploadProfilePhoto()
}
)
} else {
Image("No Profile Picture")
.resizable()
.aspectRatio(contentMode: .fill)
.frame(width: 100, height: 100)
.clipShape(Circle())
.gesture(
LongPressGesture(minimumDuration: 1.0)
.onEnded { _ in
// Perform image upload logic here
uploadProfilePhoto()
}
)
//PhotosPicker can be presented like this, but just via selection of the text as its own link
PhotosPicker(selection: $viewModel.imageSelection, matching: .images) {
Text("Open the photoPicker")
}
}
}
}
func uploadProfilePhoto() {
//present the PhotosPicker
}
}
struct ProfilePageViewTest_Previews: PreviewProvider {
static var previews: some View {
ProfilePageViewTest().environment(.managedObjectContext, PersistenceController.preview.container.viewContext)
}
}
In the example code I have both the unsatisfactory current approach, where the PhotosPicker can be opened via selection of the "Open the photoPicker" text below the image, and a placeholder for a function which I would like to have open the photopicker via long press.
The issue is I do not how to simply present the PhotoPicker as a result of a function, rather than manually creating, effectively, a button via the body of PhotosPicker(...){ <body> }
.
The end goal is actually to have uploadProfilePhoto
first display a VStack
of a few buttons: "Change profile photo", "View", "Cancel" and have the first one actually display the PhotosPicker, but if I can understand how to simply display the PhotosPicker as result of function, I can incorporate it into this overlayed button view.
2
Answers
You could try a different approach to achieve your end goal,
of
...first display a VStack of a few buttons: "Change profile photo", "View", "Cancel" and have the first one actually display the PhotosPicker
Using a
.sheet
and aPhotosPicker
as a Button, as shown in the example codeEDIT-1
You can of course use a simple
if
, such as:You can use
Instead of
Here is a full set of code.