4
votes

I'm trying to create an iPad application with a similar user interface to Apple's Mail application, i.e:

  • RootView controller (table view) on the left hand side of the split view for navigation with a multiple view hierarchy. When a table cell is selected a new table view is pushed on the left hand side
  • The new view on the left side can update the detail view.

I can accomplish both tasks, but not together. I mean I can make a multi-level table view in the RootController.

Or I can make a single-level table view in the RootController which can update the detailViewController.

Can anyone tell me how to make a multi-level table in the RootController which can update a detailViewController?

There is more source code at the link but below is the method in which I presume I have to declare a new detailViewController (which has to be put in the UISplitViewController):

- (void)tableView:(UITableView *)TableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {

NSDictionary *dictionary = [self.tableDataSource objectAtIndex:indexPath.row];

//Get the children of the present item.
NSArray *Children = [dictionary objectForKey:@"Children"];

//
if([Children count] == 0) {
    /*
    Create and configure a new detail view controller appropriate for the selection.
    */
    NSUInteger row = indexPath.row;
    UIViewController <SubstitutableDetailViewController> *detailViewController = nil;

    if (row == 0) {
        FirstDetailViewController *newDetailViewController = [[FirstDetailViewController alloc]initWithNibName:@"FirstDetailView" bundle:nil];
        detailViewController = newDetailViewController;
    }

    if (row == 1) {
        SecondDetailViewController *newDetailViewController = [[SecondDetailViewController alloc]initWithNibName:@"SecondDetailView" bundle:nil];
        detailViewController = newDetailViewController;
    }

    // Update the split view controller's view controllers array.
    NSArray *viewControllers = [[NSArray alloc] initWithObjects:self.navigationController, detailViewController, nil];
    splitViewController.viewControllers = viewControllers//nothing happens.....
    [viewControllers release];// 
}

else {

    //Prepare to tableview.
    RootViewController *rvController = [[RootViewController alloc]initWithNibName:@"RootViewController" bundle:[NSBundle mainBundle]];

    //Increment the Current View
    rvController.current_level += 1;

    //Set the title;
    rvController.current_title = [dictionary objectForKey:@"Title"];

    //Push the new table view on the stack
    [self.navigationController pushViewController:rvController animated:YES];

    rvController.tableDataSource = Children;
    [rvController.tableView reloadData]; //without this instrucion,items won't be loaded inside the second level of the table 

    [rvController release];
    }
}
1
Welcome to Stack Overflow (SO). A couple of things. First, you can format code by indenting it four spaces. I'll do this for you right after finishing this comment. Second, the people on SO who will help you are not at all "lazy" but they likely are busy. So posting your source code so that people can help you with their limited time is usually expected. - John

1 Answers

0
votes

Sorry, but I cannot post my source code as it contains sensitive information. When I have more time available I will create a separate project and upload the code somewhere.

Here are extracts of how I have done it so far (I welcome any feedback).

The RootViewController - Note I have 4 sections in my root table.

#pragma mark -
#pragma mark Table view delegate

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
    [tableView deselectRowAtIndexPath:indexPath animated:YES];

    // Detail view logic
    NSUInteger section = indexPath.section;
    UIViewController <SubstitutableDetailViewController> *detailViewController = nil;

    if (section == 2) {
        ProductSearchDetailView *viewController = [[ProductSearchDetailView alloc] initWithNibName:@"ProductSearchDetailView" bundle:nil];
        detailViewController = viewController;
        //[viewController release];
    }
    else {
        DetailViewController *defaultDetailViewController = [[DetailViewController alloc] initWithNibName:@"DetailView" bundle:nil];
        detailViewController = defaultDetailViewController;
        //[defaultDetailViewController release];
    }

    // Navigation logic 
    switch (section) {
        case 0: 
        {
            break;
        }
        case 1:
        {
            break;
        }
        case 2:
        {
            // new Navigation view
            ProductSearchViewController *viewController = [[ProductSearchViewController alloc] initWithNibName:@"ProductSearchViewController" bundle:nil];
            viewController.navigationItem.backBarButtonItem.title = @"Back";
            [self.navigationController pushViewController:viewController animated:YES];
            [viewController release];

            break;  
        }
        case 3:
        {
            StoreLocatorNavController *viewController = [[StoreLocatorNavController alloc] initWithNibName:@"StoreLocatorNavController" bundle:nil];
            viewController.navigationItem.backBarButtonItem.title = @"Back";
            [self.navigationController pushViewController:viewController animated:YES];
            [viewController release];
            break;
        }   
    }

    // Update the split view controller's view controllers array.
    NSArray *viewControllers = [[NSArray alloc] initWithObjects:self.navigationController, detailViewController, nil];
    splitViewController.viewControllers = viewControllers;
    [viewControllers release];

    // Dismiss the popover if it's present.
    if (popoverController != nil) {
        [popoverController dismissPopoverAnimated:YES];
    }

    // Configure the new view controller's popover button (after the view has been displayed and its toolbar/navigation bar has been created).
    if (rootPopoverButtonItem != nil) {
        [detailViewController showRootPopoverButtonItem:self.rootPopoverButtonItem];
    }

    [detailViewController release];

}

NSNotificationCenter part

Add this to ProductSearchViewController:

#pragma mark -
#pragma mark Table view delegate

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {

    NSDictionary *itemAtIndex = (NSDictionary *)[self.productResults objectAtIndex:indexPath.row];

    [[NSNotificationCenter defaultCenter] postNotificationName:@"updateProduct" object:itemAtIndex];
}

And finally, add this to ProductSearchDetailViewController:

- (void)viewDidLoad {
    [super viewDidLoad];

    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(updateTheProductDetails:) name:@"updateProduct" object:nil];

}

- (void)updateTheProductDetails:(NSNotification *)notification {
NSDictionary *productDictionary = [NSDictionary dictionaryWithDictionary:[notification object]];

    // product name
    _productName.text = [productDictionary objectForKey:@"ProductDescription"];
}

Hope it helps!