Question

In my app I have a drill-down type interface as follows:
My root view, which has a list of items and an "Add" button.
Selecting an item pushes the "Detail" view on the navigationController.
Selecting the "Add" button pushes an "Add" view.

How would I transition between the Add view to the Detail view?

I'm thinking of doing an unanimated "pop" on the Add view and push the Detail controller on, but how do I make the second part animated, so the detail view would either slide in vertically or fade in from the Add view?

Thanks,
Kelso

Was it helpful?

Solution

Based on Ramin's reply, you can try this way, which is used by Apple in several samples:

MyListViewController.h

#import "MyAddViewController.h"

@interface MyListViewController : UITableViewController <MyAddViewControllerDelegate> {
}

- (IBAction)add:(id)sender;
@end

MyListViewController.m

// Action for bring up add view controller
- (IBAction)add:(id)sender {
    MyAddViewController *addViewController = [[MyAddViewController alloc] initWithStyle:UITableViewStyleGrouped];
    addViewController.delegate = self;

    UINavigationController *navigationController = [[UINavigationController alloc] initWithRootViewController:addViewController];
    [self presentModalViewController:navigationController animated:YES];

    [navigationController release];
    [addViewController release];     
}

// MyAddViewController's delegate method, dismiss the add view controller in here
- (void)addViewController:(MyAddViewController *)addViewController didAddData:(MyData *)data{
if (data) {
   MyDetailViewController *detailViewController = [[MyDetailViewController alloc] initWithStyle:UITableViewStylePlain];
   detailViewController.data = data;
   [self.navigationController pushViewController:detailViewController animated:YES];
   [detailViewController release]; 
}
[self dismissModalViewControllerAnimated:YES];
}

MyAddViewController.h

@protocol MyAddViewControllerDelegate;
@class MyData;

@interface MCCourseAddTableViewController : UITableViewController {
@private
    MyData *data;
    id <MCCourseAddDelegate> delegate;
}

// MyData could be NSManagedObject if you want to use Core Data
@property(nonatomic, retain) MyData *data;
@property(nonatomic, assign) id <MyAddViewControllerDelegate> delegate;

- (void)save;
- (void)cancel;
@end

@protocol MyAddViewControllerDelegate <NSObject>
@optional
- (void)addViewController:(MyAddViewController *)addViewController didAddData:(MyData *)data;;
@end

MyAddViewController.m

- (void)save {
    if (self.delegate != nil) {
        if ([self.delegate conformsToProtocol:@protocol(MyAddViewControllerDelegate)]){
            if ([self.delegate respondsToSelector:@selector(addViewController:didAddData:)]){
                // Send data back to List View, to bring up detail view controller and dismiss add view controller
                [self.delegate addViewController:self didAddData:self.data];
            }
        }
    }
}

- (void)cancel {
    if (self.delegate != nil) {
        if ([self.delegate conformsToProtocol:@protocol(MyAddViewControllerDelegate)]){
            if ([self.delegate respondsToSelector:@selector(addViewController:didAddData:)]){
                // Send nil back to ListView, to dismiss the add view controller only
                [self.delegate addViewController:self didAddData:nil];
            }
        }
    }
}

OTHER TIPS

You could push the Add View onto the Details view and set a variable to remember that. When the user try to pop the Add View, you check the previous variable and, if set, you pop directly to the root controller(that should pop the Details view automatically).

Marco

Make the add view a modal and in there provide a "Done" (or "Save") and a "Cancel" button. If the user hits cancel, you just close the modal. If they hit Done you save the new record to the table model, then do a table reload on the root view before returning. To be nice, you can flash the newly added item.

A clean way to set this up is to make the modal controller implement a delegate that expects a 'Done' protocol method and have the root controller implement it and set itself as the delegate.

This way, the root controller is notified when the user hits 'Done' so it can encapsulate all that needs to happen. If you want to go directly from add to detail view the delegate method can do a 'push' for the newly added record and you'll get a nice transition from modal sliding down to detail view.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top