在手动创建的部分中对核心数据 tableView 行进行分组

Posted

技术标签:

【中文标题】在手动创建的部分中对核心数据 tableView 行进行分组【英文标题】:Grouping core data tableView rows in manually created sections 【发布时间】:2011-01-23 17:07:00 【问题描述】:

我有一个 Company 实体,其中包含大约 20 个字段,我想使用带有手动创建的部分标题(即:General、Financial、Misc.)的分组 tableView,但我不确定如何制作 Core Data了解如何处理这些节标题并使它们仅与我想在这些组中显示的数据相关。

例如,名称、徽标等将归入一般,预算、现金将归入财务等。

基本上,我想控制 Core data 中的哪些数据被放入每个类别并显示它。

在核心书籍示例中有以下代码:

/*
 The data source methods are handled primarily by the fetch results controller
 */

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView 
    return [[fetchedResultsController sections] count];



// Customize the number of rows in the table view.
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section 

    id <NSFetchedResultsSectionInfo> sectionInfo = [[fetchedResultsController sections] objectAtIndex:section];
    return [sectionInfo numberOfObjects];

但是我如何让它理解这些部分不在核心数据中,而是手动创建的?

【问题讨论】:

【参考方案1】:

我现在已经找到了我的问题的答案,我不知道它是否正确,但它正在工作并且欢迎 cmets。

只是为了澄清问题是什么,以及我想要做什么。

我有一个核心数据实体company,其中包含大约 10 个左右的字段,但是我不想一次性将它们全部列出,而是想对输出的字段进行分组。

例如,我有大约 6 个与现金相关的字段,例如“cash”、“marketingBudget”、“seoBudget”等,我想在 tableView 上对这些数据进行分组,但问题是我不知道如何建立关系,使 table.field.x 属于 group.x,依此类推。

我得到的答案是使用一个 PLIST/字典,它几乎反映了核心数据实体的结构;并将结构分配给我要显示的组。

我的字典是这样的;

(根)

->CompanyTpl(数组)

--> 项目 0(字典)

---> Section (String) = "General"

---> 孩子(数组 ) ------> 第 0 项(字典)

---------> 键=“名称”

---------> 值 = "公司名称" ...

如果需要,Key 将作为 Core Data 使用和显示其内容的参考。

Value 将显示在 cellForRowAtIndexPath 的位置。

所以,在我的代码中,我基本上浏览了该部分(我的意思是 tableView 部分),然后从 PLIST 中找到相关的子信息;并获取 Key/Value 并在需要时使用它。

这是代码的精简版。

- (void)viewDidLoad 
    NSString *plistPath = [[NSBundle mainBundle] pathForResource:@"CompanyTpl" ofType:@"plist"];
    self.companyDictionary = [[NSDictionary dictionaryWithContentsOfFile:plistPath] retain];

    // self.tableDataSource is a NSMutableArray
    self.tableDataSource = [self.companyDictionary objectForKey:@"CompanyTpl"];

    // Debugging info
    NSLog(@"Section = 0");

    NSLog(@"%@", [self.tableDataSource objectAtIndex:0]);

    NSLog(@"Section Name = %@", [[self.tableDataSource objectAtIndex:0] objectForKey:@"Section"]);


    NSArray *sectionChildren = [[self.tableDataSource objectAtIndex:0] objectForKey:@"Data"];

    NSLog(@"Section Children = %@", sectionChildren);
    NSLog(@"Count of Section Children = %d", [sectionChildren count]);




- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView 
    return ([self.tableDataSource count]);


// Section header
-(NSString*)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section

    NSString *title = nil;

    title = [[self.tableDataSource objectAtIndex:section] objectForKey:@"Section"];

    return title;



// Customize the number of rows in the table view.
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section 

NSInteger rows = 0;

    NSArray *sectionChildren = [[self.tableDataSource objectAtIndex:section] objectForKey:@"Data"];

    NSLog(@"Section Children = %@", sectionChildren);
    NSLog(@"Count of Section Children = %d", [sectionChildren count]);

    rows = [sectionChildren count];


    return rows;


// Customize the appearance of table view cells.
- (UITableViewCell *)tableView:(UITableView *)tableView 
         cellForRowAtIndexPath:(NSIndexPath *)indexPath 


    NSArray *sectionChildren            = [[self.tableDataSource objectAtIndex:indexPath.section] objectForKey:@"Data"];
    NSDictionary *sectionChildrenData   = [sectionChildren objectAtIndex:indexPath.row];

    //NSLog(@"Section Children data = %@", sectionChildrenData);

    NSString *scKey     = [sectionChildrenData objectForKey:@"Key"];
    NSString *scValue   = [sectionChildrenData objectForKey:@"Value"];

    NSLog(@"scKey = %@", scKey);

    // Grab the data from Core Data using the scKey



    static NSString *CellIdentifier = @"defaultCell";

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil) 
    
        cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier] autorelease];


        //cell.textLabel.text = @"test";

        cell.textLabel.text = scValue;
        cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;

    
    return cell;

这个想法是我可以在引用 Core Data 时使用 KEY 来获取其内容并将其显示在 tableView 控制器上 cellForRowAtIndexPath cell.textLabel.text 值处。

可以更深入一点,在 PLIST 中包含更多信息,例如字幕应该是什么等。

无论如何,欢迎 cmets 和想法。

谢谢。

【讨论】:

我发现 code.google.com/p/coredatalibrary 对于想要更高级地控制这类事情的人来说可能很有用。【参考方案2】:

我离答案有点近了,但我仍然无法连接核心数据项,以便它们位于某些部分。

#pragma mark -
#pragma mark Table view data source

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView 
    //return [[fetchedResultsController sections] count];
    
    //NSLog(@"%d", [self.sectionArray count] );
    
    return 4;


// Section header
-(NSString*)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section

    NSString *title = nil;
    
    switch (section) 
        case 0:
            title = @"General";
            break;
        case 1:
            title = @"Finanical";
            break;
        case 2:
            title = @"Category A";
            break;
        case 3:
            title = @"Category B";
            break;
        case 4:
            title = @"Misc";
            break;
        default:
            break;
    
    
    return title;




// Customize the number of rows in the table view.
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section 

    /*
    id <NSFetchedResultsSectionInfo> sectionInfo = [[fetchedResultsController sections] objectAtIndex:section];
    return [sectionInfo numberOfObjects];
     */
    
    NSInteger rows = 0;
    
    // The number of rows depend on the section
    switch (section) 
        case 0:
            rows = 2;
            break;
        case 1:
            rows = 3;
            break;
        case 2:
            rows = 4;
            break;
        default:
            break;
    
    
    return rows;

这样做是手动创建 4 个部分,此时名称无关紧要,然后我为每个部分创建不同数量的行。

到目前为止,一切都很好。

我遇到的问题是让 Core Data 明白在 section0.row0 我希望 textLabel 说出公司名称等。

我认为所有这些都必须在字典中,列出我想要的整个结构以及要显示的标签;然后在 cellForRowAtIndexPath 中显示我想要的字典中的数组。

即:

[root] CompanyTpl(数组)

--> 项目 0(字典)

-----> 类别(字符串)=“常规”

-----> 数据(数组)

---------> 项目 0(字典)

---------------> cdFieldName: 名称

---------------> 显示:“公司名称”

其中 cdFieldName 是对我要显示的 Core Data 中的字段名称的引用。

如果有其他方法可以做到这一点,我很想知道。

谢谢。

【讨论】:

以上是关于在手动创建的部分中对核心数据 tableView 行进行分组的主要内容,如果未能解决你的问题,请参考以下文章

在表格视图部分中对核心数据对象进行排序

在 UITableView 中对核心数据多对关系进行排序

不同 tableView 部分中的核心数据对象

向tableview添加行以添加行和核心数据

iphone SDK:使用核心数据对任意 tableview 行重新排序

如何在 TableView 的一个部分手动设置页脚(iOS)?