【问题标题】:2 UITableViews inside 1 UIViewController both loading from CoreData1个UIViewController中的2个UITableViews都从CoreData加载
【发布时间】:2017-01-30 01:21:41
【问题描述】:

我试图在 1 个 UIViewController 中拥有 2 个单独的 UITableView,但诀窍是我正在尝试这样做,以便它们都从 CoreDate 加载。

我试图通过使用与 UITableViewController 相同的样式来完成它,但我似乎遇到了问题。

我获取表格数据的方式是使用 FRC (NSFetchedResultsController),但似乎每个 UIViewController 中只有 1 个。

这是我正在使用的 2 个 FRC 提取器。

FRC 1:

func getFRCIngredients() -> NSFetchedResultsController<Ent_Ingredients> {

    let fetchReq: NSFetchRequest<Ent_Ingredients> = Ent_Ingredients.fetchRequest()
    let sortDescriptor = NSSortDescriptor(key: "order", ascending: true)
    let predicate = NSPredicate(format: "recipeRel == %@", self.recipe!)

    fetchReq.sortDescriptors = [sortDescriptor]
    fetchReq.predicate = predicate

    let frc = NSFetchedResultsController(fetchRequest: fetchReq, managedObjectContext: moc, sectionNameKeyPath: nil, cacheName: nil)

    return frc
}

FRC 2:

func getFRCDirections() -> NSFetchedResultsController<Ent_Directions> {

    let fetchReq: NSFetchRequest<Ent_Directions> = Ent_Directions.fetchRequest()
    let sortDescriptor = NSSortDescriptor(key: "order", ascending: true)
    let predicate = NSPredicate(format: "recipeRel == %@", self.recipe!)

    fetchReq.sortDescriptors = [sortDescriptor]
    fetchReq.predicate = predicate

    let frc = NSFetchedResultsController(fetchRequest: fetchReq, managedObjectContext: moc, sectionNameKeyPath: nil, cacheName: nil)

    return frc
}

在尝试将第二个 FRC 上的委托设置为 self 后,viewDidLoad() 中出现错误。当我想到它时,这是有道理的,您可能无法让它管理两组单独的数据。 错误:“libc++abi.dylib: terminating with uncaught exception of type NSException

override func viewDidLoad() {
    super.viewDidLoad()

    self.navigationItem.backBarButtonItem = UIBarButtonItem(title: "", style: UIBarButtonItemStyle.plain, target: nil, action: nil)

    tableViewIngredients.dataSource = self
    tableViewIngredients.delegate = self
    tableViewIngredients.register(UITableViewCell.self, forCellReuseIdentifier: "recipeIngredientCell")

    tableViewDirections.dataSource = self
    tableViewDirections.delegate = self
    tableViewDirections.register(UITableViewCell.self, forCellReuseIdentifier: "recipeDirectionCell")

    recipeName.text = recipe!.name
    recipeImage.image = UIImage(data: recipe!.image as! Data)

    oldName = recipe!.name!

    frcIngredients = getFRCIngredients()
    frcIngredients!.delegate = self

    do {
        try frcIngredients!.performFetch()
    } catch {
        fatalError("Failed to perform initial FRC fetch for Ingredients")
    }

    frcDirections = getFRCDirections()
    frcDirections!.delegate = self  //<- ***ERRORS HERE***

    do {
        try frcDirections!.performFetch()
    } catch {
        fatalError("Failed to perform initial FRC fetch for Ingredients")
    }

    NotificationCenter.default.addObserver(self, selector: #selector(AddRecipesVC.keyboardWillShow(notification:)), name: NSNotification.Name.UIKeyboardWillShow, object: nil)
}

我怎样才能完成我在这里尝试做的事情?我对 Xcode 和 Swift 还比较陌生,因此非常感谢任何帮助。

谢谢!

【问题讨论】:

    标签: uitableview uiviewcontroller swift3 xcode8 nsfetchedresultscontroller


    【解决方案1】:

    原来我犯了一个愚蠢的错误。我忘记了我没有更新Ent_Directions 实体中的属性名称,所以我总是调用一个不存在的属性。但以防万一这对以后有人有所帮助,这是我最终用来让 2 个 UITableView 在单个 UIViewController 中工作的代码。我删除了与 UITableViews 无关的额外代码。

    斯威夫特 3.0:

    class EditRecipesVC: UIViewController, UITableViewDataSource, UITableViewDelegate,  NSFetchedResultsControllerDelegate {
    
        // MARK: - Constants and Variables
    
        let moc = (UIApplication.shared.delegate as! AppDelegate).persistentContainer.viewContext
        var frcIngredients: NSFetchedResultsController<Ent_Ingredients>?
        var frcDirections: NSFetchedResultsController<Ent_Directions>?
        var recipe: Ent_Recipes?
    
        // MARK: - Class Loading Functions
    
        override func viewDidLoad() {
            super.viewDidLoad()
    
            self.navigationItem.backBarButtonItem = UIBarButtonItem(title: "", style: UIBarButtonItemStyle.plain, target: nil, action: nil)
    
            tableViewIngredients.dataSource = self
            tableViewIngredients.delegate = self
            tableViewIngredients.rowHeight = UITableViewAutomaticDimension
            tableViewIngredients.estimatedRowHeight = 40
    
            tableViewDirections.dataSource = self
            tableViewDirections.delegate = self
            tableViewDirections.rowHeight = UITableViewAutomaticDimension
            tableViewDirections.estimatedRowHeight = 40
    
            recipeName.text = recipe!.name
            recipeImage.image = UIImage(data: recipe!.image as! Data)
    
            oldName = recipe!.name!
    
            frcIngredients = getFRCIngredients()
            frcIngredients!.delegate = self
    
            do {
                try frcIngredients!.performFetch()
            } catch {
                fatalError("Failed to perform initial FRC fetch for Ingredients")
            }
    
            frcDirections = getFRCDirections()
            frcDirections!.delegate = self
    
            do {
                try frcDirections!.performFetch()
            } catch {
                fatalError("Failed to perform initial FRC fetch for Ingredients")
            }
    
            NotificationCenter.default.addObserver(self, selector: #selector(AddRecipesVC.keyboardWillShow(notification:)), name: NSNotification.Name.UIKeyboardWillShow, object: nil)
        }
    
        // MARK: - Outlets and Actions
    
        @IBOutlet var tableViewIngredients: UITableView!
        @IBOutlet var tableViewDirections: UITableView!
    
        // MARK: - Table View Data Source
    
        func numberOfSections(in tableView: UITableView) -> Int {
    
            var frc: NSFetchedResultsController<NSFetchRequestResult>
    
            if (tableView == tableViewIngredients) {
                frc = frcIngredients as! NSFetchedResultsController<NSFetchRequestResult>
            } else {
                frc = frcDirections as! NSFetchedResultsController<NSFetchRequestResult>
            }
    
            if let sections = frc.sections {
                return sections.count
            }
    
            return 0
        }
    
        func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    
            var frc: NSFetchedResultsController<NSFetchRequestResult>
    
            if (tableView == tableViewIngredients) {
                frc = frcIngredients as! NSFetchedResultsController<NSFetchRequestResult>
            } else {
                frc = frcDirections as! NSFetchedResultsController<NSFetchRequestResult>
            }
    
            if let sections = frc.sections {
                let currentSection = sections[section]
                return currentSection.numberOfObjects
            }
    
            return 0
        }
    
        func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    
            if (tableView == tableViewIngredients) {
                let cell: RecipeIngredientTVCell = tableView.dequeueReusableCell(withIdentifier: "recipeIngredientCell", for: indexPath) as! RecipeIngredientTVCell
    
                return cell
            } else {
                let cell: RecipeDirectionTVCell = tableView.dequeueReusableCell(withIdentifier: "recipeDirectionCell", for: indexPath) as! RecipeDirectionTVCell
    
                return cell
            }
        }
    
        // MARK: - Custom Functions
    
        func getFRCIngredients() -> NSFetchedResultsController<Ent_Ingredients> {
    
            let fetchReq: NSFetchRequest<Ent_Ingredients> = Ent_Ingredients.fetchRequest()
            let sortDescriptor = NSSortDescriptor(key: "order", ascending: true)
            let predicate = NSPredicate(format: "recipeRel == %@", self.recipe!)
    
            fetchReq.sortDescriptors = [sortDescriptor]
            fetchReq.predicate = predicate
    
            let frc = NSFetchedResultsController(fetchRequest: fetchReq, managedObjectContext: moc, sectionNameKeyPath: nil, cacheName: nil)
    
            return frc
        }
    
        func getFRCDirections() -> NSFetchedResultsController<Ent_Directions> {
    
            let fetchReq: NSFetchRequest<Ent_Directions> = Ent_Directions.fetchRequest()
            let sortDescriptor = NSSortDescriptor(key: "order", ascending: true)
            let predicate = NSPredicate(format: "recipeRel == %@", self.recipe!)
    
            fetchReq.sortDescriptors = [sortDescriptor]
            fetchReq.predicate = predicate
    
            let frc = NSFetchedResultsController(fetchRequest: fetchReq, managedObjectContext: moc, sectionNameKeyPath: nil, cacheName: nil)
    
            return frc
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-05-16
      • 1970-01-01
      • 2010-10-16
      • 1970-01-01
      • 2013-08-09
      相关资源
      最近更新 更多