2016-03-04 97 views
2

我有一個基於表視圖的應用程序,它有一個MasterTableViewController和一個DetailChildTableViewController。核心數據一對多關係不存儲其數據

MasterTableViewController在導航欄中有一個+,因此用戶可以看到在文本框中輸入該文件夾的名稱。用戶完成後,完成的時鐘和此文件夾將使用核心數據進行存儲,並在MasterTableViewController中顯示此新文件夾。

下面是該特定TableViewController代碼

MasterTableViewController

class MasterTableViewController: UITableViewController, NSFetchedResultsControllerDelegate { 


let managedObjectContext = (UIApplication.sharedApplication().delegate as! AppDelegate).managedObjectContext 
var fetchedResultsController : NSFetchedResultsController = NSFetchedResultsController() 

// Populate fetched results controller 
func getFetchedResultController() -> NSFetchedResultsController { 

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

    return fetchedResultsController 

} 


func taskFetchRequest() -> NSFetchRequest { 

    let fetchRequest = NSFetchRequest(entityName: "Folder") 
    let sortDescriptor = NSSortDescriptor(key: "name", ascending: true) 


    fetchRequest.sortDescriptors = [sortDescriptor] 
    return fetchRequest 
} 


} 
override viewDidLoad(){ 
fetchedResultsController = getFetchedResultController() 
    fetchedResultsController.delegate = self 
    do { 
     try fetchedResultsController.performFetch() 
    } catch _ { 
    } 
} 

// Table View Methods to show data in Custom UITableViewCell and Segue method.... 

代碼在該控制器的其餘部分只是有方法來顯示在表視圖單元中的數據和一個SEGUE方法當用戶點擊新創建的單元對象時,它將Core Data名稱傳遞給下一個視圖控制器。

下面是創建這個特定的對象保存和顯示MasterTableViewController

AddViewController

class addItemTableViewController: UITableViewController { 

@IBOutlet weak var FolderName: UITextField! 

// Use the same managed object to save 

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

@IBAction func Done(sender: AnyObject){ 

// Calling a function to save the folder to core data 
saveFolder() 
self.dismissViewControllerAnimated(true, completion: nil) 
} 

// Function that saves 

func saveFolder(){ 
let entityDescription = NSEntityDescription.entityForName("Folder", inManagedObjectContext: managedObjectContext) 
    let item = Folder(entity: entityDescription!, insertIntoManagedObjectContext: managedObjectContext) 

    item.name = FolderName.text! 


    // Passed Value of the color picker table view below 


    do { 
     try managedObjectContext.save() 
     print("Successfully Saved \n") 
    } catch _ { 
    } 
} 

} 

所以這段代碼基本上將新輸入的文件夾,並駁回了文件夾名稱視圖和代碼MasterTableViewController顯示這個新文件夾。

問題在於DetailChildTableViewController它是MasterTableViewController創建的每個文件夾的細節。

這裏是最終的tableview控制器的代碼

** ** DetailChildTableViewController

class DetailChildTableViewController: UITableViewController, UIPopoverPresentationControllerDelegate, NSFetchedResultsControllerDelegate { 

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

var fetchedResultsController : NSFetchedResultsController = NSFetchedResultsController() 

// Populate fetched results controller 
func getFetchedResultController() -> NSFetchedResultsController { 

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

    return fetchedResultsController 

} 


func taskFetchRequest() -> NSFetchRequest { 

    let fetchRequest = NSFetchRequest(entityName: "List") 
    let sortDescriptor = NSSortDescriptor(key: "itemListName", ascending: false) 


    fetchRequest.sortDescriptors = [sortDescriptor] 
    return fetchRequest 
} 

override func viewDidLoad() { 
    super.viewDidLoad(){ 

    // Core data 
    fetchedResultsController = getFetchedResultController() 
    fetchedResultsController.delegate = self 
    do { 
     try fetchedResultsController.performFetch() 
    } catch _ { 
    } 

    self.tableView.reloadData() 

} 

// MARK: - Display the results in table view 

override func numberOfSectionsInTableView(tableView: UITableView) -> Int { 

    if let sections = fetchedResultsController.sections { 
     return sections.count 
    } 

    return 0 
} 

override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int { 

    if let sections = fetchedResultsController.sections { 
     let currentSection = sections[section] 
     return currentSection.numberOfObjects 
    } 

    return 0 
} 

} 

此DetailChildTableViewController還具有在導航欄+按鈕,並提出了一個類似的AddViewController將數據添加到這個具有相同Core Data方法的特定文件夾。

的問題是,當我創建我的MasterTableViewController 2個實體,例如說:

  • Folder_One
  • Folder_Two

,我進入Folder_Two並創建一個列表對象在這個文件夾中,然後回到MasterTableViewController,然後選擇Folder_One,它仍然顯示我創建的同一個列表對象在Folder_Two

我該如何解決這個簡單但不清楚的問題?

這裏順便說一下我的數據模型:

TestApp。xcdatamodel

實體:

  1. 文件夾
  2. 列表

    Atributes: 名String類型的(爲文件夾實體) itemListName String類型的(爲列表實體)

    關係:(對於文件夾實體) 關係目的地:列表

注意list實體不被列爲具有文件夾的關係。我設文件夾有關係列表作爲一對多關係。

我做錯了什麼,我該如何解決這個問題?

回答

1

問題是,你的DetailChildTableViewController顯示全部List對象。您需要將其限制爲僅提取與您當前的Folder相關的List對象。要做到這一點,您必須有ListFolder之間的關係。這種關係將是一對一的,並且將成爲從FolderList的一對多關係的倒數。 (你應該幾乎總是爲每一個關係創建一個逆向,即使你覺得你不需要它,也要創建它,在這種情況下,你會看到下面的例子,你確實需要它)。所以,你的實體模型應該是這個樣子:

Folder   List 
======   ==== 
name   itemListName 
lists <------>> folder 

在你DetailChildTableViewController,添加一個新的變量,這將是Folder要爲其顯示Lists

var currentFolder : Folder? 

要限制獲取這樣它僅顯示與此文件夾相關的List對象,將謂詞添加到獲取請求中:

if let thisFolder = currentFolder { 
    fetchRequest.predicate = NSPredicate(format:"folder == %@",thisFolder) 
} 

當用戶點擊MasterTableViewController中的單元格時,在顯示DetailChildTableViewController之前,必須爲currentFolder設置正確的值。在prepareForSegue,你需要這樣的:

let indexPath = self.tableView.indexPathForSelectedRow! 
let currentFolder = self.fetchedResultsController.objectAtIndexPath(indexPath) as! Folder 
detailViewController.currentFolder = currentFolder 

同樣,AddListViewController必須有currentFolder可變知道哪些Folder新創建的List應該屬於(以及DetailChildTableViewController是塞格斯它必須設置代碼值爲currentFolder)。在AddListViewController,當你存儲List項目,你需要設置的關係:

newList.folder = currentFolder 

注意,當您設置的關係,CoreData將自動設置的反比關係(假設你定義一個)。因此newList將被添加到lists屬性currentFolder

+0

我有一個問題,'newList.folder'從哪裏來?我做了所有這些,但這最後一塊是我不記得提及或在我的應用程序中添加 – DwellingNYC

+0

此外,我有點困惑與你正在嘗試說什麼,你寫的地方「類似」,提到不同的視圖控制器我迷失在哪裏我會跟進 – DwellingNYC

+0

@harreola我用'newList'作爲例子 - 替換你在創建一個新的'List'時使用的變量名。所以'newList.folder'就是這個新創建的對象上的'文件夾'關係。 – pbasdf