ios - CoreData,递归结构……我觉得

标签 ios uitableview core-data

谢谢你看...

我什至不确定如何表达这个问题,更不用说寻找答案了...老实说,我已经尝试过,所以需要所有帮助!

这可能非常简单,因为我确信这是一种一直在发生的模式:

我的模型 (MainLevel*) 中有一个与其自身有关系的实体。

该实体用于法律的级别,唯一的要求是每个法律至少有一个(最高)级别。除此之外,从技术上讲,子级别的数量是无限的(但实际上通常约为 5 个,最多可能不超过 8-10 个)。正如所料,每个子级只有一个父级 (MainLevel.parentLevel),任何父级都可以有多个(或零个)子级 (NSSet *childLevels)。

我想做的是将这种关系的所有结构放入 UITableView 或 collectionView 中。

我有一个递归函数如下:

- (NSDictionary *)getStructureOfLawForLevel:(MainLevel *)level
{
    NSMutableDictionary *mutableDict = [[NSMutableDictionary alloc]initWithCapacity:50];
    MainLevel *currentLevel = level;
    [mutableDict setObject:currentLevel.shortName forKey:@"name"];
    if (level.childLevels) {
        NSSortDescriptor *sortDescriptor = [NSSortDescriptor sortDescriptorWithKey:@"order" ascending:YES];
        NSArray *sortdescriptors = @[sortDescriptor];
        NSArray *children = [currentLevel.childLevels sortedArrayUsingDescriptors:sortdescriptors];
        for (MainLevel *childLevel in children)
        {
            NSDictionary *dict = [self getStructureOfLawForLevel:childLevel];
            [mutableDict setObject:dict forKey:@"sublevels"];
        }
    }
    return [mutableDict copy];
}

然后在 viewWillAppear: 我有这个:

self.structure = [self getStructureOfLawForLevel:self.selectedLevel]

有了这个,我希望我在正确的路线上......(由于我现在正在排序的另一个问题而未经测试)。

尽管如此,我仍然不知道如何配置 UITableViewUICollectionView。我的意思是我确信我可以通过添加一两个计数器并以这种方式获取行数和节数来做到这一点。这看起来太复杂了,我确信一定有一个更明显的方法,我只是没有看到...

数据的唯一标准是它必须按实体实例的 .order 属性排序,这不是唯一的。我的意思是,例如,每个 childLevel 都可以有一个订单号为 1 的 childLevel。它是那个父级别中的订单。

抱歉,如果这个问题已经被问过一千次了。我试图寻找答案,但似乎找不到我正在使用的搜索词。

除了放在屏幕上,没有编辑、添加、删除之外,我没有对这些数据做任何事情……不确定这是否相关。

为清楚起见进行编辑...

我不打算进行向下钻取类型的表格 View 。我想要一个 View 中整个结构的快照,然后我可能需要从中向下钻取(使用与模型中其他实体的关系)。

为我的解决方案编辑

这是我最终做的...

- (NSArray *)getStructureAsArrayForLevel:(MainLevel *)child
{
    NSMutableArray *thisChildAndChildren = [[NSMutableArray alloc]initWithCapacity:2];
    [thisChildAndChildren addObject:child];
    if (child.childLevels)
    {
        // children exist
        // sort the children into order
        NSSortDescriptor *sortDescriptor = [NSSortDescriptor sortDescriptorWithKey:@"order" ascending:YES];
        NSArray *sortdescriptors = @[sortDescriptor];
        NSArray *children = [child.childLevels sortedArrayUsingDescriptors:sortdescriptors];
        // get an array for each child via recursion
        for (MainLevel *child in children)
        {
            [thisChildAndChildren addObject:[self getStructureAsArrayForLevel:child]];
        }
    }
    return [thisChildAndChildren copy];
}

然后我使用类似的递归函数将数组转换为 NSAttributedString 并显示在 textView 中。

我真的不喜欢递归。我不知道为什么,但我发现很难理解逻辑,当它完成时,它似乎很明显......去想想吧!

感谢大家的建议、帮助等...

最佳答案

如果您可以使用第 3 方 Controller ,请查看 TLIndexPathTools .它处理树结构。例如,尝试运行 Outline示例项目。

你的 View Controller 看起来像这样(没什么大不了的):

#import "TLTableViewController.h"
@interface TableViewController : TLTableViewController
@end

#import "TableViewController.h"
#import "TLIndexPathTreeItem.h"
@implementation TableViewController

- (void)viewDidLoad
{
    [super viewDidLoad];
    MainLevel *topLevel = nil;//get the top level object here
    TLIndexPathTreeItem *topItem = [self treeItemForLevel:topLevel depth:0];
    self.indexPathController.dataModel = [[TLTreeDataModel alloc] initWithTreeItems:@[topItem] collapsedNodeIdentifiers:nil];
}

- (void)configureCell:(UITableViewCell *)cell atIndexPath:(NSIndexPath *)indexPath
{
    // customize cell configuration here
    TLIndexPathTreeItem *item = [self.dataModel itemAtIndexPath:indexPath];
    MainLevel *level = item.data;
    cell.textLabel.text = [level description];
}

- (TLIndexPathTreeItem *)treeItemForLevel:(MainLevel *)level depth:(NSInteger)depth
{
    NSMutableArray *childItems = [NSMutableArray arrayWithCapacity:50];    
    NSSortDescriptor *sortDescriptor = [NSSortDescriptor sortDescriptorWithKey:@"order" ascending:YES];
    NSArray *sortdescriptors = @[sortDescriptor];
    NSArray *children = [level.childLevels sortedArrayUsingDescriptors:sortdescriptors];
    for (MainLevel *child in children) {
        TLIndexPathTreeItem *childItem = [self treeItemForLevel:child depth:depth + 1];
        [childItems addObject:childItem];
    }
    //set identifier to some unique identifier, if one exists. Otherwise, the item itself
    //will be used as the identifier
    id identifier = nil;
    //set cell identifier based on depth. This can be set to something unique for each
    //depth, or set to a constant value. If nil, the value "Cell" is assumed.
    NSString *cellIdentifier = [NSString stringWithFormat:@"Cell%d", depth];
    //pass "level" to the data argument. Or pass any other data, e.g. include the depth @[@(depth), level]
    TLIndexPathTreeItem *item = [[TLIndexPathTreeItem alloc] initWithIdentifier:identifier sectionName:nil cellIdentifier:cellIdentifier data:level andChildItems:children];
    return item;
}

@end

如果您想要可折叠级别,您可以子类化 TLTreeTableViewController 而不是 TLTableViewController。如果您需要更多帮助,请告诉我。

关于ios - CoreData,递归结构……我觉得,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17220891/

相关文章:

ios - 共享数据文件的应用程序的完整版和精简版

cocoa - 无法从...删除关键路径 "..."的观察者...,因为它未注册为观察者

ios - 如何仅更改操作表默认操作颜色?

ios - 导航 Controller 工具栏在显示 UIActionSheet 后变为空白

iphone - 是否可以将单词包装在 UITableViewSectionIndex 中?

ios - UITableView 的最后一行的分隔符消失/重新出现

ios - 无效的文件输出 AVAssetExport

ios - 作为调试运行与作为发布运行(仪器作为发布运行)时的 CPU 使用率较高。如何调试?

ios - 在 UITableView 的自动布局中带有填充的多行 UILabel

ios - 为什么我的 AmazonCredentials 对象无效?