【问题标题】:Building UITableView from deep JSON structure从深层 JSON 结构构建 UITableView
【发布时间】:2014-08-13 00:41:17
【问题描述】:

所以伙计们,我正面临一个我无法弄清楚的问题。我正在使用 UITableView 显示从已转换为字典的 JSON 对象收集的数据。

{
  "start_from": "2014-08-10",
  "list_tags": {
    "2014-08-12": {
      "0": [
        {
          "id": "5",
          "tag": "555"
        }
      ],
      "1": [
        {
          "id": "5",
          "tag": "556"
        }
      ],
      "-1": [
        {
          "id": "5",
          "tag": "557"
        }
      ]
    },
    "2014-08-10": {
      "0": [
        {
          "id": "5",
          "tag": "558"
        },
        {
          "id": "5",
          "tag": "565"
        },
        {
          "id": "5",
          "tag": "566"
        }
      ],
      "1": [
        {
          "id": "5",
          "tag": "559"
        }
      ],
      "-1": [
        {
          "id": "5",
          "tag": "560"
        }
      ]
    },
    "2014-08-14": {
      "0": [
        {
          "id": "5",
          "tag": "561"
        }
      ],
      "1": [
        {
          "id": "5",
          "tag": "562"
        },
        {
          "id": "5",
          "tag": "564"
        }
      ],
      "-1": [
        {
          "id": "5",
          "tag": "563"
        }
      ]
    }
  }
}

如果您查看 json 结构,它会遵循类似的内容

字典 -> list_tags -> { 特定日期(多个日期之一) -> { 特定数组(三个标识符值之一 -1,0,1) -> { 特定对象(可以是多个)}}

我正在使用表格视图,将格式化日期作为标题。这里的挑战是在相同的相应标题下显示数组 (-1,0,1) 内的所有对象。由于每个数组内部可以有多个对象,因此很难找出一个日期下存在多少对象,从而找出一个标题。

使用枚举,我获得了某个日期的对象数量。

所以我的 titleForHeader 使用

self.listTagsKeys[section];

返回特定日期所有数组下的对象数。

我的部分数量是

[self.listTags count];

我有我的行数使用与 [Date : Number Of Rows] 映射的字典

[self.tagsForDates valueForKey:[self.listTagsKeys objectAtIndex:section]];

我在这里面临的挑战是如何在同一标题下显示表格视图单元格的数据,因为我无法直接访问数据。

如果我做错了,请告诉我,以免我走错方向。 如果有人能告诉我如何在这种情况下使用迭代器,我将非常感激,而不是简单地指出这可以使用迭代器来解决,或者帮助我找到一种方法来做到这一点,或者更好地组织数据来自 JSON 结构。

如果这太令人困惑,请告诉我,以便我能够更好地解释它。

干杯!

该部分将是日期,行将是该部分下每个日期的 (-1,0,1) 中的所有对象。由于这些对象中的每一个都有一个唯一标识符作为父对象,即 -1,0,1,因此我不确定如何判断哪些行具有某个标识符。

所以 2014-08-10 将有 5 行,但使用三个图像之一(一个代表 -1,一个代表 0,一个代表 1)作为其图像视图。为了能够在特定行的图像视图中显示此图像,我需要知道它是什么类型。

【问题讨论】:

  • 使用嵌套数组看起来并不太难,但我不是 100% 在每个日期标题下你想要什么 - 也许如果你可以用表格的想法来更新你的问题看起来像 - 即在 2014-08-10 下会有 3 行 (0,1,-1) 或 5 行(0,1,-1 下的所有项目)?
  • 该部分将是日期,行将是该部分下每个日期的 (-1,0,1) 中的所有对象。由于这些对象中的每一个都有一个唯一标识符作为父对象,即-1,0,1,因此我不确定如何判断哪些行具有某个标识符。所以 2014-08-10 将有 5 行,但使用三个图像之一(一个用于 -1,一个用于 0,一个用于 1)作为其图像视图。我刚刚掌握了 stackoverflow,所以我不完全确定在哪里添加更新或编辑。
  • 您应该可以点击问题下方的“编辑”
  • 完成!感谢您的提示!
  • 只需构建一个数组以按照您想要的方式映射行。

标签: ios objective-c json uitableview


【解决方案1】:

我将首先创建一个对象来存储节和行对象。像这样的简单 NSObject 子类 -

MySectionObject.h:

@class MySectionObject;

@interface MySectionObject: NSObject {

@property (strong, nonatomic) NSDate *date;
@property (readonly,nonatomic) NSArray *rowData; 

-(id)initWithDate:(NSDate)date;
-(void)addRow:(MyRowObject *)row;

@end

我的SectionObject.m:

@interface MySectionObject: ()

@property (strong,nonatomic) NSMutableArray *rows;

@end

@implementation MySectionObject

   -(id)initWithDate:(NSDate *)date 
   {
        if (self=[super init]) {
            _date=date;
            _rows=[NSMutableArray new];
        }

        return self;
   }

   -(void)addRow(MyRowObject *)row
   {
       [self.rows addObject:row];
   }

   -(NSArray *)rowData {
   {
       return [NSArray arrayWithArray:self.rows];
   }

@end

MyRowObject.h:

@interface MyRowObject: NSObject {

@property (strong, nonatomic) NSString *id;
@property (strong, nonatomic) NSString *tag;
@property NSInteger imageType 

-(id)initWithType:(NSInteger)type id:(NSString *)id tag:(NSString *)tag;

@end

myRowObject.m:

@implementation MyRowObject

   -(id)initWithType:(NSInteger)type id:(NSString *)id tag:(NSString *)tag
   {
        if (self=[super init]) {
            _imageType=type;
            _id=id;
            _tag=tag;
        }

        return self;
   }

@end

我为这两个属性使用了字符串,因为我不确定它们是数字还是只是您的示例数据。

然后您可以简单地枚举您的 JSON 以生成嵌套数组 -

self.tableData=[NSMutableArray new];   // This is a property that stores the data for your tableview
NSDictionary *listTags = [myJson objectForKey:@"list_tags"];

for (NSString *date in listTags) {

   NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];

   [dateFormatter setDateFormat:@"yyyy-MM-dd"];
   NSDate *sectionDate = [dateFormatter dateFromString:date];

   MySectionObject *section=[MySectionObject alloc]initWithDate:sectionDate];

   NSDictionary *listTagDict = (NSDictionary *)[listTags objectForKey:date];

   for (NSString *imageType in listTagDict) {
       NSInteger *type=[imageTypes integerValue];
       NSArray *rows=[listTagDict objectForKey:imageType];
       for (NSDictionary *rowDict in rows) {
          NSString *id=(NSString *)[rowDict objectForKey:@"id"];
          NSString *tag=(NSString *)[rowDict objectForKey:@"tag"];
          MyRowObject *row=[MyRowObject alloc] initWithType:type id:id tag:tag]];
          [section addRow:row];
       }
   }

   [self.tableData addObject:section];
}

现在节数由self.tableData.count 给出,一节中的每行数由[self.tableData objectAtIndex:sectionNumber].rowData.count 给出

您可以使用MySectionObject *s=[self.tableData objectAtIndex:sectionNumber] 获取节标题的数据,并使用获取行的值

 MySectionObject *s=[self.tableData objectAtIndex:indexPath.section];
 MyRowObject *r=[s.rowData objectAtIndex:indexPath.row];

【讨论】:

  • 这就像一个魅力!您不仅解决了我的问题,还向我展示了如何做到这一点,以便我始终可以自己处理。了不起。谢谢!
【解决方案2】:
 -(void) ViewDidLoad
  {
     //json is the data you posted;    
     NSDictionary * dict = [NSJSONSerialization JSONObjectWithData:[json dataUsingEncoding:NSUTF8StringEncoding] options:NSJSONReadingMutableLeaves error:nil];
     NSMutableArray *datesArr = [NSMutableArray alloc]init];
     for(NSDictionary *d in [dict valueForKey:@"list_tags"])
         [datesArr addObject:d];
     NSMutableArray *endItems = [NSMutableArray alloc] init]; //list of all dates under list_tags
     NSMutableArray *rootItems = [NSMutableArray alloc] init]; //array of dictionary(id,tags)
     for(int i =0 i<[datesArr count]; i++)
     {
        [[datesArr objectAtIndex:i] enumerateKeysAndObjectsUsingBlock:^(id key, id object, BOOL *stop) {
        [endItems addObject:key];
        NSArray *roots = [datesArr objectAtIndex:indexPath.row];
            [[roots objectAtIndex:i] enumerateKeysAndObjectsUsingBlock:^(id key, id object, BOOL *stop) {
               [rootItems addObject:object];
            }];
        }];
     }
  }

 - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
  {
      return [endItems count];
  }

 -(NSString *) tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section
  {
     return [endItems objectAtIndex:indexPath.row];
  }

 - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
    {
       for(int i=0; i<[endItems count];i++)
        {
           if(i==section)
             //i could n't analyse how to get count for each sections.. is bit complicated
        }

    }

-(UITableViewCell *) responsesTableViewConfiguration:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{ //Your Cell implementation
   Cell.title.text = [[rootItem objectAtIndex:indexPath.row] valueForKey:@"id"];
   Cell.subtitle.text = [[rootItem objectAtIndex:indexPath.row] valueForKey:@"tag"];
}

【讨论】:

  • 我尝试了这个实现,但我无法访问最深嵌套的元素,就其父类型而言。我使用了@Paul 的实现,它的工作方式完全符合我的需要。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2022-06-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-07-03
  • 1970-01-01
相关资源
最近更新 更多