Swift 中带有自定义 TableViewCell 的核心数据图像

Posted

技术标签:

【中文标题】Swift 中带有自定义 TableViewCell 的核心数据图像【英文标题】:Core Data Image with Custom TableViewCell in Swift 【发布时间】:2016-06-13 03:59:12 【问题描述】:

我是 Swift 和 ios 开发的新手,还没有找到我的问题的具体答案。

我正在尝试使用 Core Data 填充具有 3 个标签和 2 个图像的自定义表格视图。

我阅读了可选项,甚至在故事板中创建单元格时使用字幕选项构建了类似于我现在尝试做的事情。这行得通。

我的核心数据设置在班级顶部如下所示:

// MARK: - Managed Object Context

var moc = (UIApplication.sharedApplication().delegate as! AppDelegate).managedObjectContext

// Initialize Fetch Results

var fetchedResultsController = NSFetchedResultsController()

func fetchRequest() -> NSFetchRequest 

    let fetchRequest = NSFetchRequest(entityName: "Custom")
    let sortDescriptor = NSSortDescriptor(key: "customFourImages", ascending: true)

    fetchRequest.sortDescriptors = [sortDescriptor]

    return fetchRequest


// MARK: - Retrieve Request

func getFetchRequest() -> NSFetchedResultsController 

    fetchedResultsController = NSFetchedResultsController(fetchRequest: fetchRequest(), managedObjectContext: moc!, sectionNameKeyPath: nil, cacheName: nil)

    return fetchedResultsController

我的 viewDidLoad 和 viewDidAppear 看起来像这样:

// MARK: - Fetch

    fetchedResultsController = getFetchRequest()
    fetchedResultsController.delegate = self

    do 
        try fetchedResultsController.performFetch()
     catch 
        print("Failed to Perform Initial Fetch")
        return
    
    self.tableView.reloadData()

最后,我的 cellForRowAtIndexPath 看起来像这样:

 // MARK: - Dequeue Reusable Cell

override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell 

    let cell = tableView.dequeueReusableCellWithIdentifier("cell", forIndexPath: indexPath) as! CustomTableViewCell

    // MARK: - Initiate Fetch Results for Index Path

    let custom = fetchedResultsController.objectAtIndexPath(indexPath) as! Custom

    let customLabel = custom.customLabels
    let customTwoLabel = custom.customTwoLabels
    let customThreeLabel = custom.customThreeLabels

    let image = UIImage(named: "Custom Food")
    let imageData = UIImagePNGRepresentation(image!)
    custom.customFourImages = imageData

    let images = UIImage(named: "Custom Drink")
    let imagesData = UIImagePNGRepresentation(images!)
    custom.customFiveImages = imagesData

    // MARK: - Set Items in Cell to Returned Fetched Results

    cell.customLabel?.text = "\(customLabel)"
    cell.customTwoLabel?.text = "\(customTwoLabel)"
    cell.customThreeLabel?.text = "\(customThreeLabel)"
    cell.imageView?.image = UIImage(data: custom.customFourImages!)
    cell.imageView?.image = UIImage(data: custom.customFiveImages!)

    return cell

我已经尝试了所有我能想到的排列方式,并在 Internet 和 *** 上搜索了一个具体的答案。我也不想使用字符串。我正在使用 imagePickerController。但即使在我的 imageAssets 中有图像,例如“定制食品”,“定制饮料”,图像仍然为零。

我破解不了!

【问题讨论】:

嗨,你的代码到底哪里出错了?您如何将图像保存到核心数据?您能否更新您的代码以显示自定义类的含义?图片需要保存为 NSData,你应该在使用它们之前打开你的选项。 您好 Daniel,感谢您的回复:代码在打开图像时失败。他们被发现为零。斯威夫特告诉我打开它们,例如cell.imageView?.image = UIImage(data: custom.customFourImages!) 但是每次都会崩溃。我有一个 CustomTableViewCell,其中 customLabel、customTwoLabel 等具有 IBOutlets,并且所有内容都连接在情节提要中。 我正在使用 TabBarController,每次单击自定义 tabBar 图标时,它都会崩溃,并且报告是“在展开时意外发现 nil”(lldb)。 这是我如何将图像保存在另一个名为“WorkViewController”的视图控制器中 do try moc?.save() catch print("New Photo Failed") return 【参考方案1】:

从您的 cmets 中,我无法锻炼您实际将托管对象保存到 Core Data 的位置。您提到您使用 try.moc?.save() 但您是否将个人图像保存到核心数据?此外,如果您的图像存储在设备本地,而不是从 URL 获取,那么您实际上不需要核心数据。

如果您从 URL 或其他任何地方获取图像,并假设您添加了具有 NSData 类型的 imageData 属性的实体 MyImage,您需要像这样保存对象:

class func createInManagedObjectContext(moc: NSManagedObjectContext, imgData: NSData) ->MyImage 
    let newItem = NSEntityDescription.insertNewObjectForEntityForName("MyImage", inManagedObjectContext: moc) as! MyImage
    newItem.imageData = imagData
    return newItem

将该函数添加到您的 MyImage.Swift 文件(由 Core Data 生成),这样当您需要将新图像保存到核心数据时,您只需执行以下操作:

func saveNewImage(data: DATA)
    MyImage.createInManagedObjectContext(self.managedObjectContext, imgData: data);

然后,获取您的对象:

func getSavedImages() -> [MyImage]? 
    fetchRequest.sortDescriptors = [sortDescriptor]

    do 
        return try self.managedObjectContext.executeFetchRequest(fetchRequest) as? [MyImage]
     catch 
        print("no records found")
        return nil
    

如果您已经这样做了,能否请您更新您的代码并提供更多详细信息?指出错误发生的位置(行号)。

如果您的图片在此处失败:

cell.imageView?.image = UIImage(data: custom.customFourImages!)
cell.imageView?.image = UIImage(data: custom.customFiveImages!)

您的 fetch 结果没有从 Core Data 获取记录,这可能是上述问题。

如果您的代码在这里失败:

let images = UIImage(named: "Custom Drink")
let imagesData = UIImagePNGRepresentation(images!)

您应该使用 if let img = images ... 解开您的图像对象,并且该错误很可能与您从内存中获取的 UIImage 的名称有关。

我希望这会有所帮助。

干杯。

编辑 1: 回复您的 cmets: try.moc.save 不会保存您的图像,它会保留数据模型中未决的任何更改。

您需要在核心数据中实际创建托管对象,并且您需要确保您的获取请求正在从核心数据中获取相关数据。

您的代码失败,因为 customFourImages 为 nil。术语来自:

let image = UIImage(named: "Custom Food")
let imageData = UIImagePNGRepresentation(image!)
custom.customFourImages = imageData

....

let images = UIImage(named: "Custom Drink")
let imagesData = UIImagePNGRepresentation(images!)
custom.customFiveImages = imagesData

...

cell.imageView?.image = UIImage(data: custom.customFourImages!)
cell.imageView?.image = UIImage(data: custom.customFiveImages!)

这一切似乎有点多余。

试试这个:

let image = UIImage(named: "Custom Food")
let imageData = UIImagePNGRepresentation(image!)
cell.imageView?.image = image
custom.createInManagedObjectContext(moc, imgData: imageData)
....

let images = UIImage(named: "Custom Drink")
let imagesData = UIImagePNGRepresentation(images!)
cell.imageView?.image = images //this is called in the same block? you are overwriting your imageView in the cell, maybe you have two?
custom.createInManagedObjectContext(moc, imgData: imagesData)

这会将图像保存到核心数据并将正确的图像分配给您的单元格视图(我不确定这是否会满足您将图像数据保存到核心数据的需求)。确保您了解为什么需要使用核心数据并保存适合您要求的适当托管对象。

【讨论】:

谢谢!我将新函数添加到由 Core Data 创建的 Custom.swift 文件中。该表正在加载,我可以使用 UITextFields 从我的第二个视图控制器发布 customLabel、customLabelTwo 和 customLabelThree 的值。但我仍然无法获取图像。提醒:我正在使用 imagePickerController。 是的。图像本地存储在设备上,并且还具有相机功能。是的,我允许外部存储,我认为这就是你的意思,因为我可以使用 NSFileManager。 如果你所有的图片都存储在本地,为什么还需要 Core Data 来存储你的图片? 代码在这里失败:'cell.imageView?.image = UIImage(data: custom.customFourImages!)' 所以我删除了它以加载 tableView。标签是从之前发布图像和标签的尝试中获取的,但没有图像。我正在尝试使用 try.moc.save() 将从设备检索或获取的图像保存到 CoreData。现在我知道“CoreData”中没有要检索的图像。但我可以选择它们,替换我在 UIImageView 中的占位符照片,然后“发布”,除了什么都没有出现。 因为我将 CoreData 用于其他一切。因为我是新手,所以我的目标是保持连续性。我应该改用 NSFileManager 还是 CloudKit?

以上是关于Swift 中带有自定义 TableViewCell 的核心数据图像的主要内容,如果未能解决你的问题,请参考以下文章

UITableView 中带有自定义单元格的部分

javascript中带有自定义触发器的自定义事件

ggmap中带有自定义颜色代码的Voronoi镶嵌?

Core Data 中带有自定义对象的可转换集合

欧芹验证中带有自定义域的电子邮件的正则表达式是啥

虚幻引擎 4 (ue4) 中带有自定义 c++ 蓝图函数库的蓝图循环/for/while 节点