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

若如初见. 提交于 2019-12-12 10:17:18

问题


I have a substantially working app at the moment and I'm currently going through a learning process of enhancing this. I have a TableViewController which when prompted, asks a user to input some information and when the user clicks save, that information is displayed appropriately in the table view.

I would like to ask the user to add one more bit of information and that will make up the section. This will be the date. Think of Instragram; before each picture, you have a date, etc. I want to achieve something like that where the entered date makes up the section headers and then displays them in chronological order.

I'm still learning so I'm really stuck on how to achieve this. I already have one array (called transactions) which is responsible for currently displaying everything in the table view.

Do I need to create another array to hold the entered dates?

How would I implement these methods:

sectionIndexTitlesForTableView

tableView:titleForHeaderInSection

I've not done any implementing of sections before and it's throwing me off.

The Transaction Entity has relationships to a few other entities and occasion is one of them. In the TableCell, I'm successfully displaying the result of transaction.occasion which is calling the Occasion entity and displaying it's name, etc. That Occasion entity also has a dateOfEvent attribute and basically, I want the section titles to display the dateOfEvents with the corresponding rows representing events in that date.

Any help would be much appreciated!

p.s. I'm not using an NSFetchedResultsController at the moment; I know it's easier but I want to learn this way first..


回答1:


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)
}



回答2:


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.



来源:https://stackoverflow.com/questions/19420231/creating-section-titles-in-a-table-view-controller-with-date-attribute-in-core-d

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