Creating Section Titles in a Table View Controller with date attribute in Core Data

Deadly 提交于 2019-12-08 05:48:28

I know it's too late to answer. Still just thought of posting my opinion here.

Using NSFetchedResultsController is always useful and time saving when we are using core data to store data and tableview to present it.

Here is simple scenario like whatsapp, it will group all messages day wise and sort the messages from each group:

Data model:

Message<<------->Conversation

Message{
    @NSManaged var body: String?
    @NSManaged var seen: NSNumber?
    @NSManaged var time: NSDate?
    @NSManaged var uid: String?
    @NSManaged var conversation: Conversation?

    var sectionTitle: String? {
        //this is **transient** property
        //to set it as transient, check mark the box with same name in data model
        return time!.getTimeStrWithDayPrecision()
    }

}

initialise NSFetchedResultsController as:

    let request = NSFetchRequest(entityName: "Message")
    let sortDiscriptor = NSSortDescriptor(key: "time", ascending: true)
    request.sortDescriptors = [sortDiscriptor]

    let pred = NSPredicate(format: "conversation.contact.uid == %@", _conversation!.contact!.uid!)
    request.predicate = pred

    let mainThreadMOC = DatabaseInterface.sharedInstance.mainThreadManagedObjectContext()
    fetchedResultsController = NSFetchedResultsController(fetchRequest: request, managedObjectContext: mainThreadMOC, sectionNameKeyPath: "sectionTitle", cacheName: nil)
    fetchedResultsController.delegate = self

    do {
        try fetchedResultsController.performFetch()
    } catch {
        fatalError("Failed to initialize FetchedResultsController: \(error)")
    }

data source for table view will be:

//MARK: Table view data source

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

    let sectionInfo = fetchedResultsController.sections![section]
    let n =  sectionInfo.numberOfObjects
    return n
}

func tableView(tableView: UITableView, estimatedHeightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
    return 60

}

func tableView(tableView: UITableView, titleForHeaderInSection section: Int) -> String? {

    let sectionInfo = fetchedResultsController!.sections! as [NSFetchedResultsSectionInfo]
    return sectionInfo[section].name
}

func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
    let message = fetchedResultsController.objectAtIndexPath(indexPath) as! Message
    let cell = tableView.dequeueReusableCellWithIdentifier(IncomingChatBubbleCell.identifier(), forIndexPath: indexPath) as! IncomingChatBubbleCell
    configureCell(cell, indexPath: indexPath)

    return cell
}

This will give the result like:

Hope this will help you!!!


Update
This is example implementation of getTimeStrWithDayPrecision() Date extension method:

func getTimeStrWithDayPrecision() -> String {
    let formatter = NSDateFormatter()
    formatter.timeStyle = .NoStyle
    formatter.dateStyle = .ShortStyle
    formatter.doesRelativeDateFormatting = true
    return formatter.stringFromDate(self)
}

I was not concerned whether you are using core data or any other data source.My conclusion is that you need to group occasions based on date.For this you have to filter the occasions from your data source(here numberOfOccasions) based on dateOfOccasion attribute.

I am posting some sample code here to group the occasions. Declare a dictionary object in header file such as dicOccasions.

for(int i=0;i< numberOfOccasions;i++)
    {
        if(dicOccasions==nil)dicOccasions = [[NSMutableDictionary alloc] init];
        NSString *key = [NSString stringWithFormat:@"%@",dateOfOccasion];

        NSMutableArray *ArrTemp= (NSMutableArray*)[[dicOccasions objectForKey:key] mutableCopy];
        if(ArrTemp==nil)ArrTemp = [[NSMutableArray alloc] init];
        [ArrTemp addObject:[[numberOfOccasions objectAtIndex:i] copy]];
        [dicOccasions setObject:[ArrTemp mutableCopy] forKey:key];
    }

In the tableview numberOfsections delegate you can use the count of dicOccasions In the tableView numberOfRowsInSection use follwing code.

-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    NSString *key = [self getSalesOrderKey:section];
    NSMutableArray *   Arry = [dicOccasions objectForKey:key];
    if([Arry isKindOfClass:[NSString class]])return 0;
    return [Arry count];
}
-(NSString*)getSalesOrderKey:(int)section
{
    NSArray *arr = [dicOccasions allKeys];
    arr = [arr sortedArrayUsingSelector:@selector(caseInsensitiveCompare:)];
    if (section<arr.count)return [arr objectAtIndex:section];
    return nil;
}

In viewForHeaderInSecion delegate of tableview you can use following code to get the dateOfOccasion

NSString *dateOfOccasion = [self getSalesOrderKey:section];

You can display this in a label and display as section header.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!