使用 SwiftUI 将图像从 PhotosPicker 保存到 CoreData

问题描述 投票:0回答:1

我想让我的用户使用

PhotosPicker
CoreData
添加/保存照片,但我很挣扎。实际上,我对 ID、日期、值和字符串没问题,但对图像就不是这样了。

我想我需要的一切都在这个页面中:https://www.hackingwithswift.com/forums/swiftui/saving-images-with-core-data-in-swiftui/1241 但我不知道为什么我根本无法处理它。

想知道是否有人可以告诉我我应该写什么来代替下面的评论?谢谢!

// ContentView.swift
import SwiftUI

struct ContentView: View {
    @FetchRequest(sortDescriptors: [SortDescriptor(\.name)]) var cars: FetchedResults<Car>
    @State var showForm = false

    var body: some View {
        VStack {
            Button("Add a car", action: { showForm = true })
                .fullScreenCover(isPresented: $showForm, content: { FormView() })
            ForEach(cars) { car in
                Text(car.name!)
                // Image(car.image) ???
            }
        }
    }
}
// FormView.swift
import SwiftUI
import PhotosUI

struct FormView: View {
    @Environment(\.managedObjectContext) var viewContext
    @Environment(\.dismiss) var dismiss
    @State var name = ""
    // @State var image = of type ??? from @Binding ???

    var body: some View {
        VStack {
            if #available(iOS 16.0, *) {
                TextField("Name of the car", text: $name)
                PhotosView(image: $image) // @Binding an image ???
                Button("Add", action: {
                    DataController.shared.addCar(name: name, /* image: of type ??? */, context: viewContext)
                    dismiss()
                })
            } else {
                Text("Sorry, you can't add a car!")
            }
        }
    }
}

@available(iOS 16.0, *)
struct PhotosView: View {
    @State var selectedImage: PhotosPickerItem? = nil
    @State var selectedImageData: Data? = nil
    // @Binding var image: of type ???

    var body: some View {
        if let selectedImageData, let uiImage = UIImage(data: selectedImageData) {
            ZStack {
                Image(uiImage: uiImage)
                    // .onAppear { image = something } ???
                Button("Close", action: { /* Something = nil ??? */ })
            }
        } else {
            PhotosPicker("Select an image", selection: $selectedImage, matching: .images, photoLibrary: .shared())
                .onChange(of: selectedImage) { newImage in
                    Task {
                        if let data = try? await newImage?.loadTransferable(type: Data.self) { selectedImageData = data }
                    }
                }
        }
    }
}
// CarModel.xcdatamodeld
// Entity: Car
// Attributes: id (UUID), name (String) and image (Binary Data + Allows External Storage)
// DataController.swift
import Foundation
import CoreData

struct DataController {
    // Some lines of code
    func save(context: NSManagedObjectContext) {
        try? context.save
    }
    func addCar(name: String, /* image: of type ??? */, context: NSManagedObjectContext) {
        let car = Car(context: context)
        car.id = UUID()
        car.name = name
        // car.image = of type ???
        save(context: context)
    }
}
swift image swiftui core-data photo-picker
1个回答
0
投票

我写了一个 package 使这更容易一点:

  1. 制作符合
    Mediable
    的模型:
struct MediaItem: Identifiable, Equatable, Hashable, Mediable {
   var id: UUID?
   var data: Data
   static var empty = MediaItem(id: nil, data: Data())
}
  1. 向您的视图添加属性:
@State var image = MediaItem.empty
  1. 使用
    MediaImage
    代替
    PhotosPicker
MediaImage(mediable: $image)
    .isResizable()
    .placeHolder {
        Text("Select an Image")
    }
  1. 您可以收听对
    image
    所做的更改并根据需要保存它:
.onChange(of: image) { newValue in
    DataController.shared.addCar(name: name, image: newValue.data, context: viewContext)
}

//Add Car function
func addCar(name: String, image: Data, context: NSManagedObjectContext) {
    let car = Car(context: context)
    car.id = UUID()
    car.name = name
    car.image = image
    save(context: context)
}

© www.soinside.com 2019 - 2024. All rights reserved.