learningtech
learningtech

Reputation: 33715

sample code for displaying hierarchical data of N depth in iPhone app

In my previous question, I was able to confirm that I indeed need UITableViewController to display hierarchical data for my iPhone application (using XCode 4.2).

iOS development - uitableview with infinite levels

Now I would like to see sample code that does this, something that will work in XCode 4.2. Assume the hierarchical data can be anywhere between 2 to 300 levels deep.

Where can I see sample code/sample project for something like this?

Edit - most tutorials i find seem to be for older versions of xcode.

Upvotes: 2

Views: 1470

Answers (2)

Keith Coughtrey
Keith Coughtrey

Reputation: 1495

When implementing Joel's answer, you also need to set the title of the navigation item in order to get the correct text appearring on the back buttons of each nested view:

[[childView navigationItem] setTitle:<Title from selected row>];

Also, if you are using storyboards, instead of instantiating the view controller use

[storyboard instantiateViewControllerWithIdentifier:@"myViewController"];

where myViewController is the storyboard id assigned to MyViewController

Upvotes: 1

Joel
Joel

Reputation: 16134

This question is super broad and there are multiple parts to making this work. If you break it down into discreet steps, then you can probably find the sample code for each step on SO already, or ask a more specific question. If you want help for any individual step, post a comment and I can guide you, but there is too much here to type out in a single question.

Here's how I think you need to tackle this project:

Step 1. Create your data structure

You're going to want to use an NSArray for each level. The NSArray can store a list of NSDictionaries or your own custom NSObject class. Both will work. If there is a standardized data structure then I would recommend creating your own object that you then store for each entry in the array. It makes it easier to access properties of the object than having to do a dictionary lookup for every access. Of course the object you store in the array, will need a field for another NSArray which would be the child array below it. So for example you may have something like this:

@interface MyObject : NSObject {
    NSString *nodeTitle;
    NSString *nodeDescription;
    NSArray *childArray;
}

@property (nonatomic, copy) NSString *nodeTitle;
@property (nonatomic, copy) NSString *nodeDescription;
@property (nonatomic, copy) NSArray *childArray;

In the .m file of your class you will then want to set each ivar to nil on init and release each ivar on dealloc.

Step 2. Load your data

Does your feed come down all in one big batch, or can you request it one level at a time from the server? Ideally you are not storing 300 levels deep into memory if you can avoid it (that sounds like a pretty big xml file). Ideally you are loading each level as the user steps down into the hierarchy. But perhaps there is minimal amount of data at each node and you can load it all in one step and not hog a ton of memory. You need to figure out the load routines (one shot, or on demand).

Step 3. Present your data

This is actually pretty simple. Create a view controller that uses a table view (either a UITableViewController or UIViewController with a UITableView imbedded). Create an ivar of type NSArray and a property on your view controller for this ivar (copy it). Then when you create this view controller, pass it the NSArray for the current level before you push it onto the navigation stack. Then setup the table view to present the NSArray ivar that is passed as a property to the view controller. So for example when someone click a row in the table that loads a child level, do this:

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    [tableView deselectRowAtIndexPath:indexPath animated:YES];
    int row = [indexPath row];
    MyViewController *childView = [[MyViewController alloc] init];
    childView.contentArray = ((MyObject *)[contentArray objectAtIndex:row]).childArray;
    [self.navigationController pushViewController:childView animated:YES]; 
    [childView release];     
}

This assumes you've created your standard object called MyObject for each entry in the array and it has a property called childArray which is the array for the next level down.

That'll do it.

Upvotes: 7

Related Questions