Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to pop a viewController and then Push a viewController through delegation

I have a UITableViewController that when a cell is pressed, I want the controller to pop itself, and then have the controller it pop's to, push another view controller onto the stack.

I am invoking this method because the popped-to viewController is the delegate of the tableViewController

I am currently invoking this method with a delay on it, because otherwise, everything gets screwed up waiting for the animation to end. Doing it this way seems a bit hacky and seems to me like it would fail if someone's device didn't pop the view in the allotted wait time I have given it.

Here is some of the code:

//**** code in my tableViewController ***//

[self.navigationController popViewControllerAnimated:YES];
[self.delegate cellPressedInTableViewControllerWithCalculationsModel:(id)anArgmentMyDelegateMethodTakes];



// **** Code in the viewController being popped to ****//
//CalculationsViewController is a subclass of UIViewController
CalculationsViewController *calcViewController = [[CalculationsViewController alloc] init];

//some customization code would go her

[self.navigationController performSelector:@selector(pushViewController:animated:) withObject:calcViewController afterDelay:0.75];
//this seems like the arbitrary part, the 0.75 second delay.

[calcViewController release];

There seems like there should be a better way to pop/push through delegation that will execute after the animation finishes. The wait time seems to me like it could cause unexpected problems.

I have also tried using:

 performSelectorOnMainThread:withObject:waitUntilDone

But the code just executes immediately and the view hierarchy screwed up.

I have also looked at this question: Delegation question and it has gotten me this far, but I am curious to see if there is a better way to perform such a task, Thanks.

edit: I have also tried wrapping the method in an instance of NSInvocation, and I couldn't get it to coordinate the method call until after the animation finished without arbitrarily setting the delay

like image 477
SaamJB Avatar asked Aug 22 '11 03:08

SaamJB


People also ask

How do I push a view controller?

Pushing a view controller causes its view to be embedded in the navigation interface. If the animated parameter is true , the view is animated into position; otherwise, the view is simply displayed in its final location.

What is UINavigationControllerDelegate?

It represents the delegate object for the navigation controller. 2. protocol UINavigationControllerDelegate. The View Controller must conform to this protocol while using the delegate object to modify behavior when the view controller is pushed or popped from the navigation stack.


3 Answers

The cleanest way to do more than a single push or pop of a view controller is to set the UINavigationControllers view controllers array.

For example, to pop and then push a view controller:

MyTableViewController *vc = [[MyTableViewController alloc] init];

NSMutableArray *controllers = [NSMutableArray arrayWithArray:self.navigationController.viewControllers];
[controllers removeLastObject];
[controllers addObject:vc];

[self.navigationController setViewControllers:controllers animated:YES];
like image 169
Jason Moore Avatar answered Nov 02 '22 14:11

Jason Moore


You should use a flag to overcome this situation. You set this flag in viewWillDisappear method of view controller being popped. When this flag is set then and then you can push another view controller on stack. Hope it's clear.

like image 36
Darshan Prajapati Avatar answered Nov 02 '22 14:11

Darshan Prajapati


How about when you dismiss your UIViewController containing the table you send a NSNotifcation in your viewDidDisappear method like so:

- (void)viewDidDisappear:(BOOL)animated
{
    [[NSNotificationCenter defaultCenter] postNotificationName:@"loadOtherVC" object:nil];
}

And in your parent view controller that will push a new view controller, you add an observer for that notification like so:

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

You should have a method that matches the selector.

- (void) LoadOtherVC:(NSNotification *) notification
{
    // load your other view controller you want here
}
like image 30
Zhang Avatar answered Nov 02 '22 13:11

Zhang