我正在尝试为我的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)")
}
}
}
正如您所看到的,我在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()
}
}
由于
答案 0 :(得分:0)
您可以使用sectionNameKeyPath按每个部分的属性排序,而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 ?? ""
}