Группировка данных в TableView из базовых данных в Swift 4 - PullRequest
0 голосов
/ 11 января 2019

У меня проблемы с поиском, как сгруппировать мои разделы по свойству в моей базе данных Core Data. Вот так выглядит моя БД здесь . Я пытаюсь сгруппировать свой tableView по свойству dueDate. Я загрузил свои атрибуты в массив, и именно так они отображаются. Я также планирую настроить заголовки, поэтому я хотел бы использовать стандартные методы tableView. Вот код из моего ViewController.

import UIKit
import CoreData

class MainTableViewController: UITableViewController {

    let context = (UIApplication.shared.delegate as! AppDelegate).persistentContainer.viewContext
    var taskArray = [Task]()

    override func viewDidAppear(_ animated: Bool) {
        loadData()
    }

    // MARK: - Table view functions
    override func numberOfSections(in tableView: UITableView) -> Int {
        // #warning Incomplete implementation, return the number of sections
        return 1
    }

    override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return taskArray.count
    }

    override func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
        return "Date"
    }

    override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
        return 65.00
    }

    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "taskCell", for: indexPath) as! TaskCell

        cell.nameLabel.text = taskArray[indexPath.row].name ?? "Add Items"

        if taskArray[indexPath.row].dueTime == nil {
            cell.timeLabel.text = ""
        } else {
            let timeFormatter = DateFormatter()
            timeFormatter.timeStyle = .short
            cell.timeLabel.text = timeFormatter.string(from: taskArray[indexPath.row].dueTime!)
        }

        return cell
    }

    // MARK: Add New Task
    @IBAction func addButtonPressed(_ sender: Any) {
        performSegue(withIdentifier: "newTaskSegue", sender: self)
    }


    // MARK: Save & Load Data
    func saveData() {
        do {
            try context.save()
        } catch {
            print("Error saving context \(error)")
        }
        tableView.reloadData()
    }

    func loadData() {
        let request : NSFetchRequest<Task> = Task.fetchRequest()
        let sort = NSSortDescriptor(key: "dueDate", ascending: false)
        let sort2 = NSSortDescriptor(key: "dueTime", ascending: false)
        request.sortDescriptors = [sort, sort2]

        do {
            taskArray = try context.fetch(request)
        } catch {
            print("Error loading data \(error)")
        }
        tableView.reloadData()
    }

}

Любая помощь будет высоко ценится. Спасибо!

1 Ответ

0 голосов
/ 11 января 2019

Вы можете легко сгруппировать свои данные, используя NSFetchedResultsController. Один параметр в экземпляре NSFetchedResultsController позволяет вам группировать результаты по разделам, передавая keyPath атрибута, который составляет предикат для группировки разделов.

Документация Apple объясняет это довольно ясно, с примером кода:

override func numberOfSections(in tableView: UITableView) -> Int {
    if let frc = <#Fetched results controller#> {
        return frc.sections!.count
    }
    return 0
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    guard let sections = self.<#Fetched results controller#>?.sections else {
        fatalError("No sections in fetchedResultsController")
    }
    let sectionInfo = sections[section]
    return sectionInfo.numberOfObjects
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = <#Get the cell#>
    guard let object = self.<#Fetched results controller#>?.object(at: indexPath) else {
        fatalError("Attempt to configure cell without a managed object")
    }
    // Configure the cell with data from the managed object.
    return cell
}
override func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
    guard let sectionInfo = <#Fetched results controller#>?.sections?[section] else {
        return nil
    }
    return sectionInfo.name
}
override func sectionIndexTitles(for tableView: UITableView) -> [String]? {
    return <#Fetched results controller#>?.sectionIndexTitles
}
override func tableView(_ tableView: UITableView, sectionForSectionIndexTitle title: String, at index: Int) -> Int {
    guard let result = <#Fetched results controller#>?.section(forSectionIndexTitle: title, at: index) else {
        fatalError("Unable to locate section for \(title) at index: \(index)")
    }
    return result
}

Обычно хорошей идеей (tm) является использование NSFetchedResultsController при работе с CoreData и UITableView или UICollectionView, когда вы получаете удобные уведомления (через NSFetchedResultsControllerDelegate), когда ваши данные изменяются, что позволяет вставлять или удалить ячейки из отображаемого представления.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...