You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

SwiftUI中如何将PhotosPicker图片保存至CoreData?

实现PhotosPicker选图并保存到CoreData的代码补全

以下是针对你代码中图片处理部分的完整补全,所有注释位置的内容已替换为可运行的逻辑:

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!)
                // 将CoreData中的二进制数据转为UIImage显示
                if let imageData = car.image, let uiImage = UIImage(data: imageData) {
                    Image(uiImage: uiImage)
                        .resizable()
                        .scaledToFit()
                        .frame(width: 100, height: 100)
                }
            }
        }
    }
}

FormView.swift

import SwiftUI
import PhotosUI

struct FormView: View {
    @Environment(\.managedObjectContext) var viewContext
    @Environment(\.dismiss) var dismiss
    @State var name = ""
    // 用Data类型存储选中图片的二进制数据,传递给PhotosView
    @State var selectedImageData: Data? = nil

    var body: some View {
        VStack {
            if #available(iOS 16.0, *) {
                TextField("Name of the car", text: $name)
                    .padding()
                // 绑定选中的图片数据
                PhotosView(selectedImageData: $selectedImageData)
                Button("Add", action: {
                    DataController.shared.addCar(name: name, imageData: selectedImageData, context: viewContext)
                    dismiss()
                })
                .padding()
            } else {
                Text("Sorry, you can't add a car!")
            }
        }
    }
}

@available(iOS 16.0, *)
struct PhotosView: View {
    @State var selectedImage: PhotosPickerItem? = nil
    // 绑定父视图的图片数据
    @Binding var selectedImageData: Data?

    var body: some View {
        if let selectedImageData, let uiImage = UIImage(data: selectedImageData) {
            ZStack(alignment: .topTrailing) {
                Image(uiImage: uiImage)
                    .resizable()
                    .scaledToFit()
                    .frame(width: 200, height: 200)
                Button("Close") {
                    // 清空选中的图片数据
                    selectedImageData = nil
                }
                .foregroundColor(.white)
                .padding(8)
                .background(Color.black.opacity(0.7))
                .cornerRadius(4)
            }
        } else {
            PhotosPicker("Select an image", selection: $selectedImage, matching: .images)
                .onChange(of: selectedImage) { newImage in
                    Task {
                        // 加载选中图片的二进制数据
                        if let data = try? await newImage?.loadTransferable(type: Data.self) {
                            selectedImageData = data
                        }
                    }
                }
        }
    }
}

DataController.swift

import Foundation
import CoreData

struct DataController {
    static let shared = DataController()
    
    func save(context: NSManagedObjectContext) {
        if context.hasChanges {
            do {
                try context.save()
            } catch {
                print("Save error: \(error.localizedDescription)")
            }
        }
    }
    
    // 接收图片二进制数据,存入CoreData
    func addCar(name: String, imageData: Data?, context: NSManagedObjectContext) {
        let car = Car(context: context)
        car.id = UUID()
        car.name = name
        car.image = imageData
        save(context: context)
    }
}

CoreData模型说明

  • 实体:Car
  • 属性:
    • id:类型UUID,勾选「Use default value」并设置为UUID()
    • name:类型String
    • image:类型Binary Data,勾选「Allows External Storage」(大图片会自动存到外部,减少CoreData文件体积)

内容的提问来源于stack exchange,提问作者Alexnnd

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.24 22:42:39