2014-02-13 2 views
0

Мне нужно создать UITableView, используя ответ JSON ниже (Array). У меня пока нет кода для этого, но мне бы понравилось, как бы я разделил этот массив, чтобы разместить категории и элементы на всех уровнях.Многоуровневые категории с элементами на всех уровнях в 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" 
       } 
      ] 
     } 
     ] 
    } 
} 

Я хочу, чтобы достичь следующего результата:

  • элементы
  • category1> Продукты
  • category2> Продукты

Когда категория щелкнул он будет скользить к продуктов в этой категории. Очень понравилось бы какое-то направление на этом. Некоторые продукты не будут в категориях. Как вышеприведенный пример.

ответ

3

Ну ....

  1. Вам нужно разобрать файл в формате JSON. Вы можете легко google для некоторых обучающих программ, но here is a decent one.

  2. Для того, чтобы загрузить элементы, необходимо установить UITableView. another good tutorial on UITableViews

  3. Тогда вам нужно будет узнать, как передавать данные между UIViewController. Tutorial.

Так что ваши шаги в коде будет:

  1. Разбираем JSON, чтобы отделить все элементы.
  2. Установите UITableView для отображения элементов верхнего уровня.
  3. Создайте второй UITableViewController, чтобы нажать, чтобы выбрать элемент верхнего уровня.
  4. Настройка пользовательского инициализатора для второго UITableViewController, чтобы вы могли передать ему соответствующие данные с первого контроллера вида, где вы проанализировали JSON.

Я предполагаю, что вы искали кучу кода о том, как это сделать, но это не весело :)

Позвольте мне знать, если вы столкнулись с проблемами, и я буду рад помогать.

EDIT:

Я знаю, что я сказал, что не собирается сбрасывать код, но у меня есть немного времени.

Создать 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 

EDIT:

Если вы хотите открыть и закрыть части стола, как аккордеон, взгляните на тот же код от Apple: Table View Animations and Gestures.

+0

Благодарим за случайность. Проблема, с которой я пытаюсь разобраться, - это первый уровень. Элементы, смешанные с категориями. Как я могу получить первую ячейку, чтобы показать элемент и вторую ячейку категории. Надеюсь, это имеет смысл. – Cliffordwh

+0

@SnakeBlisken Итак, вы хотите, чтобы первая ячейка отображала «Product1», вторую ячейку, чтобы отображать «Category1», третью ячейку, чтобы показать «Category2»? Затем, когда вы выбираете 'Category2', он подталкивает к таблице, которая показывает' Product2'? – random

+0

Пятно на! Но, очевидно, он должен быть динамическим, если 'JSON' возвращает 2 продукта или любое другое число (первые 2 ячейки). спасибо – Cliffordwh

Смежные вопросы