I tried your code, made only one change, this:
var normalizedCreatedAt: String {
return getTimeStrWithDayPrecision(createdAt!)
}
func getTimeStrWithDayPrecision(date: NSDate) -> String {
let formatter = NSDateFormatter()
formatter.timeStyle = .NoStyle
formatter.dateStyle = .ShortStyle
formatter.doesRelativeDateFormatting = true
return formatter.stringFromDate(date)
}
and it works fine, even for 2nd section also!
For demo purpose, I added ADD
button, by pressing it, code will add new message with current date string as content
to DB.
Here is my complete implementation:
View controller-
class ChatTableViewController: UITableViewController, NSFetchedResultsControllerDelegate {
private var fetchedResultsController: NSFetchedResultsController?
private var _mainThreadMOC: NSManagedObjectContext?
override func viewDidLoad() {
super.viewDidLoad()
// Uncomment the following line to preserve selection between presentations
// self.clearsSelectionOnViewWillAppear = false
// Uncomment the following line to display an Edit button in the navigation bar for this view controller.
// self.navigationItem.rightBarButtonItem = self.editButtonItem()
setupFetchedResultsController()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
private func getMainMOC() -> NSManagedObjectContext {
if _mainThreadMOC == nil {
let appDel = UIApplication.sharedApplication().delegate as! AppDelegate
_mainThreadMOC = NSManagedObjectContext(concurrencyType: .MainQueueConcurrencyType)
_mainThreadMOC!.persistentStoreCoordinator = appDel.persistentStoreCoordinator
_mainThreadMOC!.undoManager = nil
}
return _mainThreadMOC!
}
private func setupFetchedResultsController() {
let fetchRequest = NSFetchRequest(entityName: "Message")
let createdAtDescriptor = NSSortDescriptor(key: "createdAt", ascending: true)
fetchRequest.sortDescriptors = [createdAtDescriptor]
fetchedResultsController = NSFetchedResultsController(fetchRequest: fetchRequest, managedObjectContext: getMainMOC(), sectionNameKeyPath: "normalizedCreatedAt", cacheName: nil)
fetchedResultsController!.delegate = self
try! fetchedResultsController!.performFetch()
tableView.reloadData()
}
@IBAction func addMessage(sender: AnyObject) {
print("addMessage")
let MOC = getMainMOC()
let date = NSDate()
let _ = Message(text: "(date)", moc: MOC)
do {
try MOC.save()
}catch {
print("Error saving main MOC: (error)")
}
}
// MARK: - Table view data source
override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
return fetchedResultsController?.sections?.count ?? 0
}
override func tableView(tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
let sectionInfo = fetchedResultsController!.sections! as [NSFetchedResultsSectionInfo]
let title = sectionInfo[section].name
let headerHeight:CGFloat = tableView.sectionHeaderHeight
let headerLbl = UILabel(frame: CGRectMake(0, 0, tableView.frame.width, headerHeight))
headerLbl.backgroundColor = UIColor.lightGrayColor()
headerLbl.textAlignment = .Center
headerLbl.text = title
return headerLbl
}
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
print("--->>>")
print(section)
print(fetchedResultsController?.sections![section].objects!.count)
return (fetchedResultsController?.sections![section].objects!.count)!
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let message = fetchedResultsController?.objectAtIndexPath(indexPath) as! Message
let cell = tableView.dequeueReusableCellWithIdentifier("MessageCellId", forIndexPath: indexPath)
cell.textLabel?.text = message.content!
return cell
}
//MARK: - NSFetchedResultsControllerDelegate
func controllerWillChangeContent(controller: NSFetchedResultsController) {
tableView.beginUpdates()
}
func controller(controller: NSFetchedResultsController, didChangeSection sectionInfo: NSFetchedResultsSectionInfo, atIndex sectionIndex: Int, forChangeType type: NSFetchedResultsChangeType) {
let indexSet = NSIndexSet(index: sectionIndex)
switch type {
case .Insert:
tableView.insertSections(indexSet, withRowAnimation: .Fade)
case .Delete:
tableView.deleteSections(indexSet, withRowAnimation: .Fade)
case .Update:
fallthrough
case .Move:
tableView.reloadSections(indexSet, withRowAnimation: .Fade)
}
}
func controller(controller: NSFetchedResultsController, didChangeObject anObject: AnyObject, atIndexPath indexPath: NSIndexPath?, forChangeType type: NSFetchedResultsChangeType, newIndexPath: NSIndexPath?) {
switch type {
case .Insert:
if let newIndexPath = newIndexPath {
tableView.insertRowsAtIndexPaths([newIndexPath], withRowAnimation: .Fade)
}
case .Delete:
if let indexPath = indexPath {
tableView.deleteRowsAtIndexPaths([indexPath], withRowAnimation: .Fade)
}
case .Update:
if let indexPath = indexPath {
tableView.reloadRowsAtIndexPaths([indexPath], withRowAnimation: .Fade)
}
case .Move:
if let indexPath = indexPath, let newIndexPath = newIndexPath {
tableView.deleteRowsAtIndexPaths([indexPath], withRowAnimation: .Fade)
tableView.insertRowsAtIndexPaths([newIndexPath], withRowAnimation: .Fade)
}
}
}
func controllerDidChangeContent(controller: NSFetchedResultsController) {
tableView.endUpdates()
}
}
Message-
func getTimeStrWithDayPrecision(date: NSDate) -> String {
let formatter = NSDateFormatter()
formatter.timeStyle = .NoStyle
formatter.dateStyle = .ShortStyle
formatter.doesRelativeDateFormatting = true
return formatter.stringFromDate(date)
}
extension Message {
@NSManaged var content: String?
@NSManaged var createdAt: NSDate?
var normalizedCreatedAt: String {
return getTimeStrWithDayPrecision(createdAt!)
}
}
class Message: NSManagedObject {
// Insert code here to add functionality to your managed object subclass
override init(entity: NSEntityDescription, insertIntoManagedObjectContext context: NSManagedObjectContext?) {
super.init(entity: entity, insertIntoManagedObjectContext: context)
}
init(text: String, moc:NSManagedObjectContext) {
let entity = NSEntityDescription.entityForName("Message", inManagedObjectContext: moc)
super.init(entity: entity!, insertIntoManagedObjectContext: moc)
content = text
createdAt = NSDate()
}
}
Here is the iPad screenshot:
For testing multiple sections, I changed date & time setting os iPad.