2

i want ask how to grouping data (section) by Date?

there is my code :

import UIKit
import CoreData

class TableViewController: UITableViewController {

var myList = []

override func viewDidLoad() {
    super.viewDidLoad()


}

override func viewDidAppear(animated: Bool) {
    let appDel : AppDelegate = UIApplication.sharedApplication().delegate as! AppDelegate
    let context : NSManagedObjectContext = appDel.managedObjectContext!

    let freq = NSFetchRequest(entityName: "Item")

    myList = context.executeFetchRequest(freq, error: nil)!

    tableView.reloadData()
}

override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()

}

// MARK: - Table view data source

override func numberOfSectionsInTableView(tableView: UITableView) -> Int {

    return 1
}

override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {

    return myList.count
}


override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath) as! TableViewCell

    var object : NSManagedObject = myList[indexPath.row] as! NSManagedObject

    let name = object.valueForKeyPath("name") as! String
    let qty = object.valueForKeyPath("qty") as! Int
    let date = object.valueForKeyPath("date") as! String

    cell.nameLabel.text = name
    cell.qtyLabel.text = toString(qty)
    cell.dateLabel.text = date

    return cell
}

}

in detail : at now my date sample is just row (just 1 section default) example :

apple  1  Jul 10, 2015 (row 1)
orange 7  Jul 10, 2015 (row 2)
grape  5  Jul 11, 2015 (row 3)

i want grouping by date so this result like :

Jul 11, 2015 (section 1)
    grape 5 (row 1)
Jul 10, 2015 (section 2)
    apple 1 (row 2)
    orange 7 (row 3)

NB : section is dynamic, depends at data, and sorting date descending

anyone have solution? thx before

Hayley Guillou
  • 3,953
  • 4
  • 24
  • 34
fendy
  • 199
  • 2
  • 3
  • 11
  • I recommend using an `NSFetchedResultsController`. The [Apple docs](https://developer.apple.com/library/ios/documentation/CoreData/Reference/NSFetchedResultsController_Class/) describes it well and has boilerplate code. – pbasdf Jul 10 '15 at 07:52
  • you have sample for using NSFetchedResultsController for Swift code? – fendy Jul 10 '15 at 07:59
  • I'm not on my MacBook just now, I can post it later. Alternatively, I'm pretty sure if you create a new project using Apple's Master-Detail template, and select 'Use CoreData', the boilerplate gets copied in to the Master view controller swift file. – pbasdf Jul 10 '15 at 08:05
  • Also meanwhile, you have one added difficulty - the sort order for your `date` will be illogical, since it will be sorted as a string not a date. I would recommend rearranging that string into yyyy-mm-dd format, which will sort nicely, and then manipulating it into your preferred format for display. – pbasdf Jul 10 '15 at 08:11
  • Perhaps this helps a bit: http://stackoverflow.com/a/30544650/1187415. – Martin R Jul 10 '15 at 08:28
  • if date i set NSDate, its can simple sort than String? i already figured it for using NSFetchedResultController. thx for advice – fendy Jul 10 '15 at 10:00
  • OK to use `NSDate` to sort, but you cannot use it for the `sectionNameKeyPath`, because it includes time (down to milliseconds) so (unless you strip the time when you store the date) each record will end up in its own section. So use a `sectionIdentifier` as per @MartinR's link. – pbasdf Jul 10 '15 at 12:47

1 Answers1

0

Your list, myList, should be a form of dictionary or array of array.

for example, if it's a dictionary, it should be something like

var myList: [String: [NSManagedObject]] = [:]

which has date as key

it's all about sorting your data into right format. In viewDidAppear you can do something like

for object in freq {
        if let array = myList[object.valueForKeyPath("date")!] {
            var a = array
            a.append(object)
            myList[object.date!] = a
        } else {
            myList[object.date!] = [object]
        }
    }

then in numberOfSectionsInTableView,

return myList.count

in numberOfRowsInSection

if let a = myList[sections[section]] {
        return a.count
    }
    return 0
}

with sections sorted

var sections: [String] {
    return Array(myList.keys).sorted(<)
}

in cellForRowAtIndexPath, you can get a corresponding object.

let array = myList[sections[indexPath.section]]!
let object = array[indexPath.row]

Also you need to implement viewForHeaderInSection with

let date = sections[section]

I'm sure there is better way to do this but this is good enough to populate the table view dynamically. I just want you to see an idea. Hope it helps you.

HMHero
  • 2,333
  • 19
  • 11