如何解决如何在 SwiftUI 中对 Imagepicker 进行两次单独调用?
我希望用户能够将两个单独的图像上传到同一视图的两个不同部分。
我能够在顶部正确显示第一张图片。但是每当用户添加第二张图片时,顶部的图片会再次更新,而不是底部的图片。
下面是我的代码。任何帮助将不胜感激!
图片选择器
import SwiftUI
struct ImagePicker: UIViewControllerRepresentable {
@Environment(\.presentationMode) var presentationMode
@Binding var image: UIImage?
func makeUIViewController(context: UIViewControllerRepresentableContext<ImagePicker>) -> UIImagePickerController {
let picker = UIImagePickerController()
picker.delegate = context.coordinator
return picker
}
func updateUIViewController(_ uiViewController: UIImagePickerController,context: UIViewControllerRepresentableContext<ImagePicker>) {
}
func makeCoordinator() -> Coordinator {
Coordinator(self)
}
}
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.image = uiImage
}
parent.presentationMode.wrappedValue.dismiss()
}
}
内容视图
import SwiftUI
struct ContentView: View {
@State private var firstImage: Image? = Image("PlaceholderImage")
@State private var secondImage: Image? = Image("PlaceholderImage")
@State private var inputImage1: UIImage?
@State private var inputImage2: UIImage?
@State private var showingImagePicker = false
var body: some View {
VStack{
Form {
Section(header: Text("First Image")){
firstImage!
.resizable()
.aspectRatio(contentMode: .fit)
.frame(minWidth: 0,maxWidth: .infinity,minHeight: 0,maxHeight: 200,alignment: .center)
.clipShape(Rectangle())
.onTapGesture { self.showingImagePicker = true }
.sheet(isPresented: $showingImagePicker,onDismiss: loadImage1) {
ImagePicker(image: self.$inputImage1)
}
}
Section(header: Text("Second Image")){
secondImage!
.resizable()
.aspectRatio(contentMode: .fit)
.frame(minWidth: 0,onDismiss: loadImage2) {
ImagePicker(image: self.$inputImage2)
}
}
}
}
}
func loadImage1() {
guard let inputImage = inputImage1 else { return }
firstImage = Image(uiImage: inputImage)
}
func loadImage2() {
guard let inputImage = inputImage2 else { return }
secondImage = Image(uiImage: inputImage)
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
解决方法
问题的根本原因是使用 sheet(isPresented:)
,这在 iOS 14 上可能会出现问题,因为它加载了它的第一次渲染的工作表内容(在您的情况下,第一个图像的 ImagePicker
),然后不会像人们预期的那样更新(例如参见 SwiftUI @State and .sheet() ios13 vs ios14)。
解决方案是使用 sheet(item:)
。在您的情况下,这还涉及一些其他重构以使事情按预期工作。这是我想出的:
struct ContentView: View {
@State private var inputImage1: UIImage?
@State private var inputImage2: UIImage?
@State private var activeImagePicker : ImagePickerIdentifier? = nil
enum ImagePickerIdentifier : String,Identifiable {
case picker1,picker2
var id : String {
return self.rawValue
}
}
var image1 : Image {
if let inputImage1 = inputImage1 {
return Image(uiImage: inputImage1)
} else {
return Image("Placeholder")
}
}
var image2 : Image {
if let inputImage2 = inputImage2 {
return Image(uiImage: inputImage2)
} else {
return Image("Placeholder")
}
}
var body: some View {
VStack{
Form {
Section(header: Text("First Image")){
image1
.resizable()
.aspectRatio(contentMode: .fit)
.frame(minWidth: 0,maxWidth: .infinity,minHeight: 0,maxHeight: 200,alignment: .center)
.clipShape(Rectangle())
.onTapGesture { self.activeImagePicker = .picker1 }
}
Section(header: Text("Second Image")) {
image2
.resizable()
.aspectRatio(contentMode: .fit)
.frame(minWidth: 0,alignment: .center)
.clipShape(Rectangle())
.onTapGesture { self.activeImagePicker = .picker2 }
}
}
.sheet(item: $activeImagePicker) { picker in
switch picker {
case .picker1:
ImagePicker(image: $inputImage1)
case .picker2:
ImagePicker(image: $inputImage2)
}
}
}
}
}
请注意,我删除了您的 onDismiss
函数,因为这里没有必要,但是如果您确实需要它来进行实际实现,我建议您使用 {{1} } 在单个 onDisappear
上,这将让您区分哪个被解雇了。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。