2015-07-11 58 views
1

我有一個自定義的UITableView,它負責重新排列單元格的動畫,並且與不使用核心數據的標準測試數組完美配合。在覈心數據中使用'didMoveCellFromIndexPathToIndexPathBlock'

當使用具有To Many關係的兩個實體「文件夾」和「項目」使用核心數據的應用程序進行嘗試時,我收到一條錯誤消息。

[(項目)]不具有稱爲exchangeObjectAtIndex

構件;

tableView.didMoveCellFromIndexPathToIndexPathBlock = {(fromIndexPath: NSIndexPath, toIndexPath: NSIndexPath) -> Void in 

let delegate:AppDelegate = UIApplication.sharedApplication().delegate as! AppDelegate 
let context: NSManagedObjectContext = delegate.managedObjectContext! 

self.itemsArray.exchangeObjectAtIndex(toIndexPath.row, withObjectAtIndex: fromIndexPath.row) 

    var error: NSError? = nil 
    if !context.save(&error) { abort() } 

} 

這是因爲:

的NSSet中,的NSMutableSet,和NSCountedSet類聲明 編程接口對象的無序集合。

所以我試着將NSSet轉換爲NSMutableArray來管理對象順序。

func itemsMutableArray() -> NSMutableArray { 
    return NSMutableArray(array: (item.allObjects as! [Item]).sorted{ $0.date.compare($1.date) == NSComparisonResult.OrderedAscending }) 
} 

但是,然後我在我的tableview中得到以下錯誤;這是因爲可變數組是AnyObject,所以swift不相信它具有title屬性。

cell.textLabel?的.text = folderMutableArray [indexPath.row] .title僞

於是我回去的地方,我開始。我只是試圖創建一個簡單的列表並重新排列對象的順序。

這裏是我的Folder類:

class Folder: NSManagedObject { 

@NSManaged var date: NSDate 
@NSManaged var title: String 
@NSManaged var item: NSSet 

/// Method 1 - Converting to a NSMutableArray 

// func itemsMutableArray() -> NSMutableArray { 
// return NSMutableArray(array: (item.allObjects as! [Item]).sorted{ $0.date.compare($1.date) == NSComparisonResult.OrderedAscending }) 
// } 


// Method 2 - creating an array of type Item 
func itemArray() -> [Item] { 
    let sortByDate = NSSortDescriptor(key: "Date", ascending: true) 
    return item.sortedArrayUsingDescriptors([sortByDate]) as! [Item] 
} 
} 

生產力應用程序做這一切的時候,所以我知道這是可能的,但不知如何,有誰知道我錯了或者有任何意見或建議?

回答

4

這很容易實現。您需要將名爲index的房產添加到您的Item。將其設置爲整數類型,並且每當添加新的Item時,都會將此值設置爲您希望項目出現的索引。此屬性應作爲NSManaged屬性添加到核心數據模型和項目類中。

接下來,您需要爲Folder類添加一個瞬態屬性,名爲arrayOfItems(當然,您可以將其重命名爲任何您想要的)。在覈心數據模型中將其設置爲瞬態和可變形。

在你Folder類執行以下操作:

class Folder: NSManagedObject { 

    @NSManaged var date: NSDate 
    @NSManaged var title: String 
    @NSManaged var item: NSSet 
    @NSManaged var arrayOfItems: [Items] 

    override func awakeFromFetch() { 
     super.awakeFromFetch() 
     self.regenerateItems() 
    } 

    func regenerateItems() { 
     let desc = NSSortDescriptor(key: "index", ascending: true) 
     if let array = item.sortedArrayUsingDescriptors([desc]) as? [Item] { 
      self.arrayOfItems = array 
     } 
    } 

} 

現在,只要你取的Folder任何情況下,你會得到Item個正確的排序和可變數組。只有其他兩種情況需要考慮。

它們是因爲awakeFromFetch只是在您從Core Data獲取數據時才被調用。所以,你必須考慮其他情況。

添加新Item

當你添加你需要手動添加新ItemarrayOfItemsItem或者你需要調用regenerateItems()一旦你完成添加新Item。例如,讓我們假設在你的代碼的某個地方在創建初始數據:以上

var folder = NSEntityDescription.insertNewObjectForEntityForName("Folder", inManagedObjectContext: self.managedObjectContext!) as! Folder 
var firstItem = NSEntityDescription.insertNewObjectForEntityForName("Item", inManagedObjectContext: self.managedObjectContext!) as! Item 
// assuming that you have an inverse relationship from Item to Folder 
// line below will assign it and will add your firstItem to Folder's 
// NSSet of items 
firstItem.folder = folder 

// at this point your firstItem is added to your Folder but 
// arrayOfItems is empty. So, you should call 
folder.arrayOfItems = [firstItem] 
// or you can call folder.regenerateItems() 

典指的情況,當你創建你的初始數據。如果某處在你的代碼中添加一個新的Item到已經有一些Items你有以下的文件夾:

var newItem = NSEntityDescription.insertNewObjectForEntityForName("Item", inManagedObjectContext: self.managedObjectContext!) as! Item 
// assuming that you have an inverse relationship from Item to Folder 
// line below will assign it and will add your newItem to Folder's 
// NSSet of items 
newItem.folder = someExistingFolder 

// at this point your newItem is added to your Folder but 
// arrayOfItems is not yep updated and does not include newItem 
// so you should either call 
folder.arrayOfItems.append(newItem) 
// or you can call folder.regenerateItems() 

花事Items

此外,當你在表視圖中移動Item是你需要在arrayOfItems中更改其索引和訂單。實現這一目標最簡單的方法很可能會改變在arrayOfItems項目的順序,然後通過此陣內將其分配給所有項目正確的新指標迭代:

func tableView(tableView: UITableView, moveRowAtIndexPath sourceIndexPath: NSIndexPath, toIndexPath destinationIndexPath: NSIndexPath) { 
    let itemThatMoved = currentFolder.arrayOfItems[sourceIndexPath.row] 
    currentFolder.arrayOfItems.removeAtIndex(sourceIndexPath.row) 
    currentFolder.arrayOfItems.insert(itemThatMoved, atIndex:destinationIndexPath.row) 
    var currentIndex = 0 
    for item in currentFolder.arrayOfItems { 
     item.index=currentIndex 
     currentIndex++ 
    } 
} 

讓我知道如果這能幫助或者你有任何其他問題。

P.S.我強烈建議您將您的關係名稱從item更改爲items。複數名稱items更合乎邏輯NSSet

+0

非常感謝你的回覆,非常翔實。是否按照您的建議重構了一些代碼並更新了Core Data模型和Classes。 我瞭解到目前爲止的更新,但不確定將項目添加到文件夾時的意思。爲什麼我需要追加到arrayOfItems創建一個項目的數組呢?或者爲什麼我需要在之後調用'regenerateItems()'?我所要求的理由是完全理解代碼,而不是盲目地更新希望得到結果的代碼。我用代碼更新了我的問題以添加一個項目 – RileyDev

+0

給我幾分鐘我將在我的回答中對此展開 –

+0

我將接受此答案,非常感謝您的幫助我真的很感激它!非常豐富。仍然在研究一個錯誤,當我移動單元格時,其他單元格將其名稱更改爲它們要替換的單元格。例如。如果它們是5個單元 - 1,2,3,4,5,並且我將3放置在5應該替代1,2,4,5,3的末端,則其他單元將它們的文本更新到替換單元,例如, 1,2,3(4),4(5),3(移動的單元格) – RileyDev