278204
278204

Reputation: 598

dismissViewControllerAnimated:completion: Push to another ViewController

I'm just wondering if it's possible to push to a ViewController right after I dismissed one.

I've been trying with this:

     -(void)dismiss{
    //send information to database here

    [self dismissViewControllerAnimated:YES completion:^{
                    NSLog(@"Dismiss completed");
                    [self pushtoSingle:post_id];
                }];
}

-(void)pushtoSingle:(int)post_id{
    Single1ViewController *svc = [self.storyboard instantiateViewControllerWithIdentifier:@"SingleView"];
    svc.post_id = post_id;
    svc.page = 998;
    [self.navigationController pushViewController:svc animated:YES];
}

And this:

    -(void)dismiss{

//send information to database here

[self dismissViewControllerAnimated:YES completion:^{
                    NSLog(@"Dismiss completed");
                    Single1ViewController *svc = [self.storyboard instantiateViewControllerWithIdentifier:@"SingleView"];
                    svc.post_id = post_id;
                    svc.page = 998;
                    [self.navigationController pushViewController:svc animated:YES];
                }];
}

But with no success. The view is successfully is dismissed but the push is never initialized.. Is there another known way around the problem?

Upvotes: 16

Views: 30871

Answers (4)

278204
278204

Reputation: 598

Yep, I figured it out. I simply posted a notification after I dismissed the ViewController B to A and then received the notification in A and pushed to C..

Dismissing in B:

[self dismissViewControllerAnimated:YES completion:^{

    [[NSNotificationCenter defaultCenter] postNotificationName:@"pushToSingle" object:nil userInfo:[NSDictionary dictionaryWithObject:[NSNumber numberWithInt:post_id1] forKey:@"post_id"]];
}];

Receiving in A:

-(void)viewWillAppear:(BOOL)animated{   
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(pushToSingle:) name:@"pushToSingle" object:nil];
}

-(void)pushToSingle:(NSNotification *)notis{
    NSDictionary *dict = notis.userInfo;
    int post_id = [[dict objectForKey:@"post_id"] intValue];

    NSLog(@"pushing to single");
    Single1ViewController *svc = [self.storyboard instantiateViewControllerWithIdentifier:@"SingleView"];
    svc.post_id = post_id;
    svc.page = 998;
    [self.navigationController pushViewController:svc animated:YES];

}

Thanks, Jacky Boy!

Upvotes: 32

Daisuke Adachi
Daisuke Adachi

Reputation: 639

Category:

class Category {
    var name: String = ""
}

FirstViewController:

class FirstViewController: UIViewController {

    func addNewCategory() {
        let category = Category()

        let secondViewController = SecondViewController(category: category)

        secondViewController.didCreateCategory = { (category: Category) in
            let thirdViewController = ThirdViewController(category: category)
            self.navigationController?.pushViewController(thirdViewController, animated: true)
        }

        let secondNavigationController = UINavigationController(rootViewController: secondViewController)
        presentViewController(secondNavigationController, animated: true, completion: nil)
    }

}

SecondViewController:

class SecondViewController: UIViewController {

    @IBOutlet weak var categoryNameTextField: UITextField!
    var didCreateCategory: ((category: Category) -> ())?
    var category: Category

    init(category: Category) {
        self.category = category
        super.init(nibName: nil, bundle: nil)
    }

    convenience required init(coder aDecoder: NSCoder) {
        self.init(coder: aDecoder)
    }

    override func viewDidLoad() {
        super.viewDidLoad()

        navigationItem.rightBarButtonItem = UIBarButtonItem(barButtonSystemItem: .Add,
            target: self, action: "createCategory")
    }

    func createCategory() {
        dismissViewControllerAnimated(true, completion: {
            self.category.name = self.categoryNameTextField.text
            self.didCreateCategory!(category: self.category)
        })
    }

}

ThirdViewController:

class ThirdViewController: UIViewController {
    var category: Category

    init(category: Category) {
        self.category = category
        super.init(nibName: nil, bundle: nil)
    }

    convenience required init(coder aDecoder: NSCoder) {
        self.init(coder: aDecoder)
    }
}

Upvotes: 0

Nathan Kellert
Nathan Kellert

Reputation: 618

This is more of just adding to the answer provide above presented by robot6.

If you are going to be adding the new view as a child view you should really consider also adding the following to the parent view as well.

-(void)viewDidDisappear:(BOOL)animated{
    [[NSNotificationCenter defaultCenter] removeObserver:self];

} 

In my case I was launching a AlertView based off of the int passed back through the notifications NSDictionary.Then I was presenting the same child view again after accepting the AlertView.

-(void)pushToSingle:(NSNotification *)notis{     
 NSDictionary *dict = notis.userInfo;
        int post_id = [[dict objectForKey:@"post_id"] intValue];
        NSLog(@"%d", post_id);


        if (post_id == 1) {
            UIAlertView *alert = [[UIAlertView alloc]

                                  initWithTitle:@"Sign Up"
                                  message:@"Are you sure you want to cancel?"
                                  delegate:self
                                  cancelButtonTitle:@"Cancel"
                                  otherButtonTitles: @"Accept", nil];
            alert.tag = 1;
            post_id = 4;
            [alert show];
        }
}

Heres what was happening.

Alert from parent view in child view

So, through the above answer I learned that basically anything you do in view 1 will go again in your child view as though it was still on your parent view as you never removed the NSNotification observer and the observer is still active.

Now this may not cause problems for everyone but it will eat up system resources if you dont really need it as ARC wont release the observer until the parent view is no longer active or unless you tell it to do so in your viewDidDisapper

Upvotes: 0

Rui Peres
Rui Peres

Reputation: 25917

Take out the animation. Like this:

[self dismissViewControllerAnimated:NO completion:^{
                NSLog(@"Dismiss completed");
                [self pushtoSingle:post_id];
            }];

I had cases where multiple animations would create strange behaviors.

Edit 1.0:

Try this:

[self performSelector:@selector(pushtoSingle:) withObject:post_id afterDelay:0.3];

Edit 2.0:

Just notice now... You are dismissing your UIViewController and you are trying to push a new one from your just dismissed UIViewController. In theory, here:

 [self dismissViewControllerAnimated:YES completion:^{
                    NSLog(@"Dismiss completed");
                    [self pushtoSingle:post_id];
                }];

On your completion block, self will be nil, because you just dismiss it. Push the new UIViewController from the current UIViewController. Example, if your current UIViewController is B:

A -> B

After dismiss:

A

Push the new one:

A -> C

Upvotes: 2

Related Questions