2014-02-13 53 views
0

我必须使用下面的(阵列)JSON响应创建UITableView。我还没有代码,但是会喜欢一些方向,我将如何拆分这个数组以适应各个级别的类别和项目。UITableView中所有级别上的项目的多级别类别

{ 
    "result":{ 
     "products":[ 
     { 
      "id":"4", 
      "product_code":"PR04", 
      "title":"Product1", 
      "franchisee_id":"118" 
     } 
     ], 
     "categories":[ 
     { 
      "id":"8", 
      "name":"Category1" 
     }, 
     { 
      "id":"20", 
      "name":"Category2", 
      "products":[ 
       { 
        "id":"9", 
        "product_code":"PR07", 
        "title":Product2, 
        "franchisee_id":"118" 
       } 
      ] 
     } 
     ] 
    } 
} 

我想达到以下结果:

  • 项目
  • 组别>项目
  • 类别2>项目

当一个类被点击它会滑到该类别的产品。真的会喜欢这方面的一些方向。有些产品不会分类。像上面的例子一样。

回答

3

嗯....

  1. 您需要解析JSON文件。您可以轻松地谷歌一些教程,但here is a decent one

  2. 接下来,您将需要设置一个UITableView来加载项目。 another good tutorial on UITableViews

  3. 然后你将需要学习如何在UIViewController之间传递数据。 Tutorial

所以在代码的步骤将是:

  1. 解析JSON的所有元素分开。
  2. 设置UITableView以显示顶级元素。
  3. 创建第二个UITableViewController以在顶级项目被选定后推送到。
  4. 为第二个UITableViewController设置自定义初始值设定项,以便您可以从解析JSON的第一个视图控制器传递相关数据。

我假设你正在寻找如何做到这一串代码,但是这没有乐趣:)

让我知道如果您遇到任何麻烦,我会很高兴帮助。

编辑:

我知道我说我不打算抛售代码,但我有一些额外的时间。

创建NSObject子类,称为ProductObject,使.h这个样子的:

#import <Foundation/Foundation.h> 

@interface ProductObject : NSObject 
@property NSString *productCode, *productTitle, *franchiseId, *productId; 
@end 

不要做任何事情的.m


创建另一个NSObject子类,称为CategoryObject,使.h这个样子的:

#import <Foundation/Foundation.h> 

@interface CategoryObject : NSObject 
@property NSString *categoryName, *categoryId; 
@property NSArray *products; 
@end 

再次,不需要做任何的.m


现在,在课堂上要显示UITableView将在产品及目录(这是所有在.m,该.h为空):

#import "ViewController.h" 
#import "CategoryObject.h" 
#import "ProductObject.h" 

@interface ViewController() 

//Hooked in from IB 
@property (weak, nonatomic) IBOutlet UITableView *table; 

//Our UITableView data source 
@property NSMutableDictionary *tableObjects; 

@end 


@implementation ViewController 


/** 
Parses a the local JSON file 
*/ 
- (void)parseJSON { 
    NSString *filePath = [[NSBundle mainBundle] pathForResource:@"test" ofType:@"json"]; 

    //création d'un string avec le contenu du JSON 
    NSString *myJSON = [[NSString alloc] initWithContentsOfFile:filePath encoding:NSUTF8StringEncoding error:NULL]; 

    NSError *error; 
    NSDictionary *topLevleJSON = [NSJSONSerialization JSONObjectWithData:[myJSON dataUsingEncoding:NSUTF8StringEncoding] options:kNilOptions error:&error]; 

    if (error) { 
     NSLog(@"Error serializing JSON: %@", error.localizedDescription); 
     return; 
    } 


    NSArray *products = topLevleJSON[@"products"]; 
    NSArray *categories = topLevleJSON[@"categories"]; 

    //Use a NSDictonary so that it contains an NSArray of ProductObjects for the "Products" key, and an array of CategoryObjects for the "Category" key. 
    self.tableObjects = [NSMutableDictionary new]; 

    //Parse all the products 
    NSMutableArray *productsInJSON = [NSMutableArray new]; 
    [products enumerateObjectsUsingBlock:^(NSDictionary *productObject, NSUInteger idx, BOOL *stop) { 
     ProductObject *product = [self createProductObjectFromDictionary:productObject]; 
     [productsInJSON addObject:product]; 
    }]; 

    //Set the array of ProductObjects for the key @"Products" 
    [self.tableObjects setObject:productsInJSON forKey:@"Products"]; 


    //Parse all the categories 
    NSMutableArray *categoriesInJSON = [NSMutableArray new]; 
    [categories enumerateObjectsUsingBlock:^(NSDictionary *categoryObject, NSUInteger idx, BOOL *stop) { 
     CategoryObject *category = [self createCategoryObjectFromDictionary:categoryObject]; 
     [categoriesInJSON addObject:category]; 
    }]; 

    //Set the array of CategoryObjects for key @"Categories" 
    [self.tableObjects setObject:categoriesInJSON forKey:@"Categories"]; 

    [self.table reloadData]; 
} 

/** 
Creates a ProductObject from an NSDictonary. 

@param dictionary The dictonary describing the Product parsed from JSON 

@return A pretty formatted ProductObject 
*/ 
- (ProductObject*)createProductObjectFromDictionary:(NSDictionary*)dictionary { 
    ProductObject *product = [ProductObject new]; 
    product.productTitle = dictionary[@"title"]; 
    product.productCode = dictionary[@"product_code"]; 
    product.franchiseId = dictionary[@"franchisee_id"]; 
    product.productId = dictionary[@"id"]; 

    return product; 
} 


/** 
Creates a Category from an NSDictionary 

@param dictionary The dictonary describing the Category parsed from JSON 

@return A pretty formatted CategoryObject 
*/ 
- (CategoryObject*)createCategoryObjectFromDictionary:(NSDictionary*)dictionary { 

    CategoryObject *category = [CategoryObject new]; 
    category.categoryId = dictionary[@"id"]; 
    category.categoryName = dictionary[@"name"]; 

    //Check to see if the "products" key exist for the category, if we don't check and just look for it, we will get a crash if it doesn't exist. 
    if ([[dictionary allKeys] containsObject:@"products"]) { 
     NSArray *categoryProducts = dictionary[@"products"]; 

     //Parse all the Products for the Category. 
     NSMutableArray *categoryProductsFormatted = [NSMutableArray new]; 
     [categoryProducts enumerateObjectsUsingBlock:^(NSDictionary *productObject, NSUInteger idx, BOOL *stop) { 
      ProductObject *product = [self createProductObjectFromDictionary:productObject]; 
      [categoryProductsFormatted addObject:product]; 
     }]; 

     category.products = [NSArray arrayWithArray:categoryProductsFormatted]; 
    } 
    else { 
     category.products = nil; 
    } 

    return category; 
} 


#pragma mark - 
#pragma mark - UITableView delegate 

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { 
    return [[self.tableObjects allKeys] count]; 
} 

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { 

    //Get the key for this section 
    NSString *key = [[self.tableObjects allKeys] objectAtIndex:section]; 

    //Return the number of objects for this key. 
    return [(NSArray*)[self.tableObjects objectForKey:key] count]; 
} 

- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section { 
    return [[self.tableObjects allKeys] objectAtIndex:section]; 
} 

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { 

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"CellIdentifier"]; 

    if (!cell) { 
     cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"CellIdentifier"]; 
    } 

    //Get all the NSArray associated with this section, which will be an array of ProductObjects or an array of CategoryObjects 
    NSString *key = [[self.tableObjects allKeys] objectAtIndex:indexPath.section]; 
    NSArray *sectionobjects = (NSArray*)[self.tableObjects objectForKey:key]; 

    id object = [sectionobjects objectAtIndex:indexPath.row]; 

    //Set the cell text based on what kind of object is returned 
    if ([object isKindOfClass:[ProductObject class]]) { 
     cell.textLabel.text = [(ProductObject*)object productTitle]; 
    } 

    else if ([object isKindOfClass:[CategoryObject class]]) { 
     cell.textLabel.text = [(CategoryObject*)object categoryName]; 
    } 

    return cell; 
} 

#pragma mark - 
#pragma mark - UITableView delegate 
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { 


    [tableView deselectRowAtIndexPath:indexPath animated:YES]; 

    NSString *key = [[self.tableObjects allKeys] objectAtIndex:indexPath.section]; 
    NSArray *sectionobjects = (NSArray*)[self.tableObjects objectForKey:key]; 

    id object = [sectionobjects objectAtIndex:indexPath.row]; 

    //They selected a product 
    if ([object isKindOfClass:[ProductObject class]]) { 

     ProductObject *product = (ProductObject*)object; 

     NSLog(@"%@", product.productTitle); 
     NSLog(@"%@", product.productCode); 
     NSLog(@"%@", product.productId); 
    } 


    //They selected a Category 
    else if ([object isKindOfClass:[CategoryObject class]]) { 

     //Check to see if the CategoryObject has any ProductObjects associated with it 
     if ([(CategoryObject*)object products]) { 

      //Now you will need to pass array of ProductObjects this along to your next view controller. 
      NSArray *cateogryProducts = [(CategoryObject*)object products]; 


      //For demonstration purposes, i'll run through and print out all the Products for this Category 
      [cateogryProducts enumerateObjectsUsingBlock:^(ProductObject *product, NSUInteger idx, BOOL *stop) { 
       NSLog(@"%@", product.productTitle); 
       NSLog(@"%@", product.productCode); 
       NSLog(@"%@", product.productId); 
      }]; 
     } 

    } 

} 



- (void)viewDidLoad 
{ 
    [super viewDidLoad]; 
    // Do any additional setup after loading the view, typically from a nib. 

    //Start parsing the JSON 
    [self parseJSON]; 
} 

- (void)didReceiveMemoryWarning 
{ 
    [super didReceiveMemoryWarning]; 
    // Dispose of any resources that can be recreated. 
} 

@end 

编辑:

如果你想要打开并像手风琴表的近端部分,看看苹果的同一代码:Table View Animations and Gestures

+0

感谢您的随机。问题即时尝试让我的头是第一级。这些项目与类别混合在一起。我将如何获得第一个单元格显示该项目和第二个单元格的类别。希望这是有道理的。 – Cliffordwh

+0

@SnakeBlisken所以,你要第一个单元格以显示'Product1',第二单元以显示'Category1',第三单元格以显示'Category2'?那么当你选择'Category2'时,它会推到一个显示'Product2'的表格? – random

+0

现货!但显然它需要是动态的,以防'JSON'返回2个产品或任何数字(前2个单元格)。谢谢 – Cliffordwh