UITableView中所有级别上的项目的多级别类别 [英] Multi level categories with items on all levels in UITableView

查看:66
本文介绍了UITableView中所有级别上的项目的多级别类别的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我必须使用下面的 JSON 响应创建 UITableView (数组)。我还没有这方面的代码,但我希望如何分割这个数组以适应所有级别的类别和项目。

I have to create a UITableView using the JSON response below ( Array ). I have no code for this yet but would love some direction to how i would split this array to accommodate categories and items on all levels.

 {
   "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"
               }
            ]
         }
      ]
   }
}

我想达到以下结果:


  • items

  • Category1> items

  • Category2> items

单击某个类别时,它将滑动到该类别中的产品。真的很喜欢这个方向。有些产品不属于类别。就像上面的例子一样。

When a category is clicked it would slide to the products in that category. Would really love some direction on this. Some products will not be in categories. Like the example above.

推荐答案

嗯....


  1. 您需要解析JSON文件。您可以轻松谷歌搜索一些教程,但这里是一个体面的

接下来,您需要设置 UITableView 来加载项目。 关于 UITableView的另一个好教程 s

Next you are going to need to setup a UITableView to load the items. another good tutorial on UITableViews

然后你将需要学习如何在 UIViewController之间传递数据秒。 教程

Then you are going to need to learn how to pass data between UIViewControllers. Tutorial.

因此,您在代码中的步骤将是:


  1. 解析JSON以分离所有元素。

  2. 设置 UITableView 以显示顶级元素。

  3. 创建第二个 UITableViewController ,在选择顶级项目后推送到。

  4. 为第二个 UITableViewController 设置一个自定义初始值设定项,这样你就可以从解析<$的第一个视图控制器传递相关数据。 C $ C> JSON 。

  1. Parse the JSON to separate all the elements.
  2. Setup a UITableView to display the top level elements.
  3. Create a second UITableViewController to push to after a top level item has been selected.
  4. Setup a custom initializer for the second UITableViewController so you can pass it relevant data from the first view controller where you parsed the JSON.

我假设你正在寻找一堆关于如何做到这一点的代码,但这并不好玩:)

如果您遇到任何麻烦,请告诉我,我很乐意为您提供帮助。

Let me know if you run into any troubles and I will be glad to help.

编辑:

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

I know I said I wasn't going to dump code but I have some extra time.

创建一个名为 ProductObject NSObject 子类并制作 .h 看起来像这样:

Create an NSObject subclass called ProductObject and make the .h look like this:

#import <Foundation/Foundation.h>

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

不要对做任何事情。 m

创建另一个 NSObject 子类名为 CategoryObject ,并使 .h 看起来像这样:

Create another NSObject subclass called CategoryObject and make the .h look like this:

#import <Foundation/Foundation.h>

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

同样,不需要对<$ c $做任何事情c> .m 。

现在,在要显示的类中 UITableView 产品和类别(全部在 .m .h 为空):

Now, in the class that you want to display the UITableView will the Products and Categories (this is all in the .m, the .h is empty):

#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






编辑:


如果您想像手风琴一样打开和关闭桌子的某些部分,请查看Apple的相同代码:表格视图动画和手势

If you are wanting to open and close parts of the table like an accordion, take a look at Apple's same code: Table View Animations and Gestures.

这篇关于UITableView中所有级别上的项目的多级别类别的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆