来自核心数据的集合视图 - 最后选择的内容首先出现

Posted

技术标签:

【中文标题】来自核心数据的集合视图 - 最后选择的内容首先出现【英文标题】:Collection View from Core Data- Last Selected Appears First 【发布时间】:2015-08-30 10:46:50 【问题描述】:

当前功能

我有一个集合视图,其中每个单元格都由一个图像和一个标签组成。它是视图控制器中的集合视图。目前,视图可以从两个数组(一个用于图像名称,一个用于标签名称)中编译和加载。当用户点击一个单元格时,它会将它们带到一个新的视图控制器。

所需的功能

但是,我想添加这样的功能,即当用户返回集合视图时,他们点击的单元格现在是第一个(左上角)。此新订单应保存到核心数据并成为新的默认订单。

迄今为止的进展

我已经开始尝试实现此功能,但将原始数组导入 CoreData 是一项挑战。我无法将原始数组放入 CoreData 和从 CoreData 获取中构建的 collectionView 中。集合视图构建,但没有我的图像/标签,只有一些 CoreData 代码加载到我的标签中......

这是我在 viewDidLoad 中得到的:

    //Fetch & sort the list from Core Data
    let appDelegate = UIApplication.sharedApplication().delegate as! AppDelegate
    let managedContext = appDelegate.managedObjectContext!
    let fetchRequest = NSFetchRequest(entityName: "MenuItem_llcv")
    let sortDescriptor = NSSortDescriptor(key: "displayOrder", ascending: true )
    fetchRequest.sortDescriptors = [ sortDescriptor ]
    var error: NSError?
    let fetchedResults = managedContext.executeFetchRequest(fetchRequest, error: &error) as? [NSManagedObject]

    //Check fetch results
    //If fetch was successful, the results are assigned to the context object
    if let results = fetchedResults 
        ll_ColViewOrder_Context = results
        println("Fetch succesful, although possibly empty.")
     else 
        println("Could not fetch \(error), \(error!.userInfo)")
    

    //First-time user check
    //If CoreData has the arrays, do nothing. If it doesn't, load them in.
    if ll_ColViewOrder_Context.count > 8 
        println("Fetch result: Previously stored list found in Core Data.")
     else 
        //Set arrays to populate cells
        cvListNames = ["Label 1", "Label 2", "Label 3", "Label 4", "Label 5"]

        cvListImgs = ["image1","image2","image3","image4","image5"]

        let entityVar =  NSEntityDescription.entityForName("MenuItem_llcv", inManagedObjectContext: managedContext)
        let listItem = NSManagedObject(entity: entityVar!, insertIntoManagedObjectContext:managedContext)

        var numberToStore = 1

        for ea_Name in cvListNames 
            listItem.setValue(ea_Name, forKey: "name")
        
        for ea_ImgName in cvListImgs 
            listItem.setValue(ea_ImgName, forKey: "imgName")
        
        for ea_OrderNum in cvListImgs 
            listItem.setValue(numberToStore, forKey: "displayOrder")
            ++numberToStore
        
        managedContext.save(nil)
        println("Context now contains \(ll_ColViewOrder_Context)")
    

这是我的表的构建基础:

func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell 

    let cell = collectionView.dequeueReusableCellWithReuseIdentifier(reuseIdentifier, forIndexPath: indexPath) as! LifeList_CollectionViewCell

    //Assign images
    let image = UIImage(named: "\(ll_ColViewOrder_Context[indexPath.row])")
    cell.cvCell_Image.image = image

    //Assign list names
    let title = "\(ll_ColViewOrder_Context[indexPath.row])"
    cell.cvCell_Name.text = title

【问题讨论】:

【参考方案1】:

您只创建了一个 NSManagedObject,然后通过为其每个属性分配值进行迭代。但是你仍然只有一个对象。您需要为数组中的每个值创建一个新的 NSMO:

    //Set arrays to populate cells
    cvListNames = ["Label 1", "Label 2", "Label 3", "Label 4", "Label 5"]
    cvListImgs = ["image1","image2","image3","image4","image5"]

    let entityVar =  NSEntityDescription.entityForName("MenuItem_llcv", inManagedObjectContext: managedContext)

    for (index, value) in enumerate(cvListNames) 
        let listItem = NSManagedObject(entity: entityVar!, insertIntoManagedObjectContext:managedContext)
        listItem.setValue(value, forKey: "name")
        let imageName = cvListImgs[index]
        listItem.setValue(imageName, forKey: "imgName")
        listItem.setValue(index, forKey: "displayOrder")
        ll_ColViewOrder_Context.append(listItem)
    
    managedContext.save(nil)
    println("Context now contains \(ll_ColViewOrder_Context)")

我使用了enumerate 函数来获取index 中每个值的cvListNames。然后,此 index 既可用于在 cvListImgs 中查找相应的图像,也可用于填充 displayOrder 属性。我还添加了一行来将每个新的 NSMO 附加到支持您的集合视图的数组中。

另外,在填充集合视图的代码中,您需要使用valueForKey 来提取相关属性的值:

let cell = collectionView.dequeueReusableCellWithReuseIdentifier(reuseIdentifier, forIndexPath: indexPath) as! LifeList_CollectionViewCell
//Assign images
let currentObject = ll_ColViewOrder_Context[indexPath.row]
let imageName = currentObject.valueForKey("imgName")
let listName = currentObject.valueForKey("name")
let image = UIImage(named: imageName)
cell.cvCell_Image.image = image
//Assign list names
cell.cvCell_Name.text = listName

【讨论】:

你就是@pbasdf 我真的很感谢你对我的不同问题给出的许多答案。我必须做的唯一调整是 'var imageName: String = currentObject.valueForKey("imgName") as! String' 因为没有“as!String”,我收到一条错误消息,说我正在尝试分配 AnyObject。但除了这些小细节之外,您的代码也很好用。要让最后一个选定的单元格现在移到列表中的第一个,在 didSelectCell 方法中,我应该只执行核心数据“在位置 1 处插入”,然后删除旧对象? @DaveG 不客气。我忘了铸造valueForKey。您可能想调查为您的实体创建 NSManagedObject 子类,然后您可以使用 .访问器 (currentObject.imgName) 而不是 valueForKey。然后编译器可以进行类型检查。 移动选定的单元格并不是那么容易。首先使用 NSFetchedResultsController 正确构建表视图。有样板代码。这个想法是 FRC 底层的 fetch 应该使用displayOrder 进行排序。要移动项目,不要删除并重新添加对象,只需修改其displayOrder 属性,使其排在其他项目之前。 哇哦!做到了。 var newOrderNum = 1 for eaObj in ll_ColViewOrder_Context eaObj.setValue(newOrderNum, forKey: "displayOrder") ++newOrderNum 感谢您的帮助!

以上是关于来自核心数据的集合视图 - 最后选择的内容首先出现的主要内容,如果未能解决你的问题,请参考以下文章

选择器视图中来自核心数据的数据

使用 .net 核心,我如何在视图中显示来自数据库的 html 内容

MySQL-视图和索引

如何根据集合视图中的单元格选择来控制表格视图的内容?

UICollectionView 总是在当前之前显示上一个选择

从数组中检索索引,使用该索引在pickerview中选择一行