CoreData按字符串

时间:2017-03-19 20:12:16

标签: ios xcode swift3

我正在尝试为我的tableview创建标题,这些标题由日期分隔,这是一个字符串。我正在使用核心数据和NSFetchResultsController。

我基本上制定了一个基于字符串日期分隔事件的议程。

我无法在swift 3中找到如何做到这一点。

我的代码如下:

import UIKit
import CoreData

class MainVC: UIViewController, UITableViewDelegate, UITableViewDataSource, NSFetchedResultsControllerDelegate {

    @IBOutlet weak var tableView: UITableView!
    @IBOutlet weak var segControl: UISegmentedControl!

    var fetchedResultsController: NSFetchedResultsController<Event>!

    override func viewDidLoad() {
        super.viewDidLoad()
        tableView.delegate = self
        tableView.dataSource = self
        //generateTest()
        attemptFetchRequest()
    }


    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

        if let cell = tableView.dequeueReusableCell(withIdentifier: "eventCell", for: indexPath) as? EventCell {
            configureCell(cell: cell, indexPath: indexPath as NSIndexPath)
            return cell
        }

        return EventCell()
    }

    //calling configure cell in this VC too

    func configureCell(cell: EventCell, indexPath: NSIndexPath) {
        let event = fetchedResultsController.object(at: indexPath as IndexPath)
        cell.configureCell(event: event)
    }

    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {

        if let events = fetchedResultsController.fetchedObjects , events.count > 0 {
            let event = events[indexPath.row]
            performSegue(withIdentifier: "DetailsVC", sender: event)
        }
    }

    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        if segue.identifier == "DetailsVC" {
            if let dest = segue.destination as? DetailsVC {
                if let event = sender as? Event {
                    dest.eventToEdit = event
                }
            }
        }
    }



    func numberOfSections(in tableView: UITableView) -> Int {
        if let sections = fetchedResultsController.sections {
            return sections.count
        }
        return 0
    }

    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        if let sections = fetchedResultsController.sections {
            let sectionInfo = sections[section]
            return sectionInfo.numberOfObjects
        }

        return 0
    }

    func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
           //no idea what to do here
    }


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

    func attemptFetchRequest() {
        let fetchRequest: NSFetchRequest<Event> = Event.fetchRequest()
        let dateSort = NSSortDescriptor(key: "date", ascending: false) //sort by date
        let tagSort = NSSortDescriptor(key: "tag", ascending: false) //sort by tag


        if segControl.selectedSegmentIndex == 0 {
            fetchRequest.sortDescriptors = [dateSort]
        } else {
            fetchRequest.sortDescriptors = [tagSort]
        }

        let controller = NSFetchedResultsController(fetchRequest: fetchRequest, managedObjectContext: context, sectionNameKeyPath: nil, cacheName: nil)

        controller.delegate = self

        self.fetchedResultsController = controller

        do {
            try fetchedResultsController.performFetch()
        } catch {
            let err = error as NSError
            print("\(err)")
        }
    }
}

Here is my core data entities, date and tag are both strings

正如您所看到的,我在attemptFetch()函数中按日期排序,但如何按日期在表格视图中将它们拆分?

谢谢。

EDIT !!!

我修复了它,内容保存到正确的部分但是,每次我从tableview添加或删除时,内容都不会重新加载,当我按分段控件时,没有任何反应。

我正在重新加载表数据,所以我不确定发生了什么......

代码:

导入UIKit 导入CoreData

类MainVC:UIViewController,UITableViewDelegate,UITableViewDataSource,NSFetchedResultsControllerDelegate {

@IBOutlet weak var tableView: UITableView!
@IBOutlet weak var segControl: UISegmentedControl!

var fetchedResultsController: NSFetchedResultsController<Event>!

override func viewDidLoad() {
    super.viewDidLoad()
    tableView.delegate = self
    tableView.dataSource = self
    //generateTest()
    attemptFetchRequest()
}


func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

    if let cell = tableView.dequeueReusableCell(withIdentifier: "eventCell", for: indexPath) as? EventCell {
        configureCell(cell: cell, indexPath: indexPath as NSIndexPath)
        return cell
    }

    return EventCell()
}

//calling configure cell in this VC too

func configureCell(cell: EventCell, indexPath: NSIndexPath) {
    let event = fetchedResultsController.object(at: indexPath as IndexPath)
    cell.configureCell(event: event)
}

func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {

    if let events = fetchedResultsController.fetchedObjects , events.count > 0 {
        let event = events[indexPath.row]
        performSegue(withIdentifier: "DetailsVC", sender: event)
    }
}

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
    if segue.identifier == "DetailsVC" {
        if let dest = segue.destination as? DetailsVC {
            if let event = sender as? Event {
                dest.eventToEdit = event
            }
        }
    }
}



func numberOfSections(in tableView: UITableView) -> Int {
    if let sections = fetchedResultsController.sections {
        return sections.count
    }
    return 0
}

func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    if let sections = fetchedResultsController.sections {
        let sectionInfo = sections[section]
        return sectionInfo.numberOfObjects
    }

    return 0
}

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

func attemptFetchRequest() {
    let fetchRequest: NSFetchRequest<Event> = Event.fetchRequest()
    let dateSort = NSSortDescriptor(key: "date", ascending: false) //sort by date
    let tagSort = NSSortDescriptor(key: "tag", ascending: false) //sort by tag


    if segControl.selectedSegmentIndex == 0 {
        fetchRequest.sortDescriptors = [dateSort]
    } else {
        fetchRequest.sortDescriptors = [tagSort]
    }

    let controller = NSFetchedResultsController(fetchRequest: fetchRequest, managedObjectContext: context, sectionNameKeyPath: nil, cacheName: nil)

    controller.delegate = self

    self.fetchedResultsController = controller

    do {
        try fetchedResultsController.performFetch()
    } catch {
        let err = error as NSError
        print("\(err)")
    }
}

func controllerWillChangeContent(_ controller: NSFetchedResultsController<NSFetchRequestResult>) {
    tableView.beginUpdates()

}

func controllerDidChangeContent(_ controller: NSFetchedResultsController<NSFetchRequestResult>) {
    tableView.endUpdates()
}

func controller(_ controller: NSFetchedResultsController<NSFetchRequestResult>, didChange anObject: Any, at indexPath: IndexPath?, for type: NSFetchedResultsChangeType, newIndexPath: IndexPath?) {

    switch(type) {

    case.insert:
        if let indexPath = newIndexPath {
            tableView.insertRows(at: [indexPath], with: .fade)
        }
        break
    case.delete:
        if let indexPath = indexPath {
            tableView.deleteRows(at: [indexPath], with: .fade)
        }
        break
    case.update:
        if let indexPath = indexPath {
            if let cell = tableView.cellForRow(at: indexPath) as? EventCell {
                configureCell(cell: cell, indexPath: indexPath as NSIndexPath)
            }


        }
        break
    case.move:
        if let indexPath = indexPath {
            tableView.deleteRows(at: [indexPath], with: .fade)
        }
        if let indexPath = newIndexPath {
            tableView.insertRows(at: [indexPath], with: .fade)
        }
        break

    }
}

func generateTest() {
    let event = Event(context: context)
    event.detail = "going to a meeting"
    event.location = "san fran"
    event.tag = "meeting"
    event.title = "Google meeting"

    let event2 = Event(context: context)
    event2.detail = "going to a meeting"
    event2.location = "LA"
    event2.tag = "lunch"
    event2.title = "lunch with musk"

    let event3 = Event(context: context)
    event3.detail = "going to a meeting"
    event3.location = "Toronto"
    event3.tag = "date"
    event3.title = "visiting GF"

    let event4 = Event(context: context)
    event4.detail = "going to a meeting"
    event4.location = "san fran"
    event4.tag = "meeting"
    event4.title = "Google meeting"

    ad.saveContext()
}


@IBAction func segControllerChanged(_ sender: Any) {

    attemptFetchRequest()
    tableView.reloadData()
}

}

由于

2 个答案:

答案 0 :(得分:0)

您可以使用section​Name​Key​Path按每个部分的属性排序,而NSFetchedResultsController会相应地返回每个获取部分的部分和对象,而不是返回已获取的对象,而不是按顺序排列。

您目前将其设置为nil

  

获取对象的关键路径,用于确定它们的部分   属于。

答案 1 :(得分:0)

如果您在Core Data中将日期存储为Date会更好,因为您可能会发现字符串不会按正确的日期顺序排序。

您需要在sectionKeyPath

上指定NSFetchedResultsController
func attemptFetchRequest() {
    let fetchRequest: NSFetchRequest<Event> = Event.fetchRequest()

    var key: String

    let dateSort = NSSortDescriptor(key: "date", ascending: false) //sort by date
    let tagSort = NSSortDescriptor(key: "tag", ascending: false) //sort by tag


    if segControl.selectedSegmentIndex == 0 {
        key = "date"
    } else {
        key = "tag"
    }

    let sort = NSSortDescriptor(key: key, ascending: false)

    fetchRequest.sortDescriptors = [sort]
    fetchRequest.sectionKeyPath = key

    let controller = NSFetchedResultsController(fetchRequest: fetchRequest, managedObjectContext: context, sectionNameKeyPath: nil, cacheName: nil)

    controller.delegate = self

    self.fetchedResultsController = controller

    do {
        try fetchedResultsController.performFetch()
    } catch {
        let err = error as NSError
        print("\(err)")
    }
}

然后,您可以使用NSFetchedResultsSectionInfo获取该部分的名称:

func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
    let sectionInfo = self.fetchedResultsController.sections?[section] 
    return sectionInfo?.name ?? ""
}