发生数组索引错误:索引超出范围



问题

你好。我正在学习SwiftUI。

我尝试使用PHPickerController从图库中挑选多张照片,并显示多个视图,这些视图逐一表示每张照片。然而,每当我尝试访问vm.images的任何索引时,都会发生致命错误。我该如何解决这个问题?

我的源代码如下

已解决

问题来自vm.images,我认为.onChange修改器是在所有图像都保存到vm.images中之后操作的。但事实并非如此。

我在调用PickerTabView时添加了if语句,解决了这个问题;相当简单的

// Added code
if let images = vm.images {
if images.count > 0 {
PickerTabView()
}
}

struct PickerTabView: View {
@EnvironmentObject var vm: ViewModel

var body: some View {
TabView {
if let images = vm.images{
ForEach(images, id: .self) { image in
PickerSettingView(image: image)
}
}
}
.tabViewStyle(.page)
}
}
struct ImagesPicker: UIViewControllerRepresentable {
@Binding var selectedImages: [UIImage]?

//var selectionLimit: Int
//var filter: PHPickerFilter?
var itemProvider: [NSItemProvider] = []

func makeUIViewController(context: Context) -> some PHPickerViewController {
var configuration = PHPickerConfiguration()
configuration.selectionLimit = 20
configuration.filter = .images

let picker = PHPickerViewController(configuration: configuration)
picker.delegate = context.coordinator
return picker
}

func updateUIViewController(_ uiViewController: UIViewControllerType, context: Context) {

}

func makeCoordinator() -> Coordinator {
return ImagesPicker.Coordinator(parent: self)
}

class Coordinator: NSObject, PHPickerViewControllerDelegate, UINavigationControllerDelegate {
var parent: ImagesPicker

init(parent: ImagesPicker) {
self.parent = parent
}

func picker(_ picker: PHPickerViewController, didFinishPicking results: [PHPickerResult]) {
picker.dismiss(animated: true)

if !results.isEmpty {
parent.itemProvider = []
parent.selectedImages = []
}

parent.itemProvider = results.map(.itemProvider)
loadImage()
}

private func loadImage() {
for itemProvider in parent.itemProvider {
if itemProvider.canLoadObject(ofClass: UIImage.self) {
itemProvider.loadObject(ofClass: UIImage.self) { image, error in
DispatchQueue.main.sync {
if let image = image as? UIImage {
self.parent.selectedImages?.append(image)
}
}
}
}
}
}


}
}

struct PickerHomeView: View {
@EnvironmentObject var vm: ViewModel
@State private var isSelected = false

var body: some View {
NavigationView {
VStack {
NavigationLink("Tab View", isActive: $isSelected) {
PickerTabView()
}
.hidden()

HStack {
Button {
vm.showPicker()
} label: {
ButtonLabel(symbolName: "photo.fill", label: "Photos")
}
}
Spacer()
}
.sheet(isPresented: $vm.showPicker) {
ImagesPicker(selectedImages: $vm.images)
.ignoresSafeArea()
}
.onChange(of: vm.images, perform: { _ in
isSelected = true
})
}
}
}
struct PickerSettingView: View {
@EnvironmentObject var vm: ViewModel
var image: UIImage
let myImage = MyImage(category: Category.unCategorized)
@State private var selectedCategory: Category = Category.unCategorized

var body: some View {
VStack {
Image(uiImage: image)
.resizable()
.scaledToFit()
.frame(minWidth: 0, maxWidth:.infinity)

SwiftUI.Picker("Category Picker", selection: $selectedCategory) {
Text("Formal").tag(Category.formal)
Text("Casual").tag(Category.casual)
Text("Semi Formal").tag(Category.semiFormal)
}
.pickerStyle(.segmented)
.padding([.leading, .trailing], 16)

HStack {
Button {
if vm.selectedImage == nil {
vm.addMyImage(category: selectedCategory, image: image)
} else {
vm.updateSelected()
}
} label: {
ButtonLabel(symbolName: vm.selectedImage == nil ? "square.and.arrow.down.fill" :
"square.and.arrow.up.fill",
label: vm.selectedImage == nil ? "Save" : "Update")
}
}
}
}
}
class ViewModel: ObservableObject {
@Published var images: [UIImage]?
@Published var showPicker = false
}

我认为loadImage中的image没有添加到self.parent.selectedImages中当它为零时,也就是说,当ViewModel中的images为零时,就像开始时一样。因此,每当您尝试访问vm.imagesimages数组的任何索引时,应用程序都会崩溃。

您可以在loadImage(也请注意.async)中尝试添加图像:

DispatchQueue.main.async {
if let image = image as? UIImage {
if self.parent.selectedImages == nil { self.parent.selectedImages = [] }
self.parent.selectedImages!.append(image)
}
}

相关内容

  • 没有找到相关文章

最新更新