2

I need to retain child view controller after its dismissal to move it back when needed without extra processing in child view controller. I have tried achieving it using below links:

https://developer.apple.com/library/ios/featuredarticles/ViewControllerPGforiPhoneOS/ImplementingaContainerViewController.html

How does View Controller Containment work in iOS 5?

These links (and similar others) did serve the purpose of bringing child view controller or dismissing it but not "retaining it". Please find my code below:

/* Adding a child view controller */
self.detailsViewController = [self.storyboard instantiateViewControllerWithIdentifier:@"DetailsViewController"];
self.detailsViewController.name = @"DetailsText";
// data to do "processing in viewDidLoad of child"
self.detailsViewController.someOtherDataForProcessing = someOtherDataForProcessing;
self.detailsViewController.delegate = self;
[self addChildViewController:self.detailsViewController];
self.detailsViewController.view.frame = CGRectMake(0, self.view.frame.size.height, self.view.frame.size.width, 200);
[self.view addSubview:self.detailsViewController.view];


/* Bringing the child up on swipe gesture */
[UIView animateWithDuration:0.5 animations:^{
    self.detailsViewController.view.frame = CGRectMake(0, 100, self.view.frame.size.width, 200);
}  completion:^(BOOL finished) {
    [self.detailsViewController didMoveToParentViewController:self];
}];


/* Moving child down when back pressed on child */
[UIView animateWithDuration:0.5 animations:^{
    [self.detailsViewController willMoveToParentViewController:nil];

    self.detailsViewController.view.frame = CGRectMake(0, self.view.frame.size.height, self.view.frame.size.width, 200);
} completion:^(BOOL finished) {
    [self.detailsViewController.view removeFromSuperview];
    [self.detailsViewController removeFromParentViewController];
}];

If i need to bring child controller "again on swipe on parent", I have to go through the whole process again. What i need is just to do "Bringing the child up on swipe gesture" process and not instantiate again because instantiating will do processing of data in child controller (time consuming).

I am a noob to iOS app programming so please bear with me if this is an obvious question.

Community
  • 1
  • 1
Ruchit B
  • 23
  • 4
  • How is `self.detailsViewController` declared? It should be `strong`. – Cyrille Apr 11 '16 at 09:51
  • @property (strong, nonatomic) DetailsViewController *detailsViewController; I think the issue is in these lines: [self.detailsViewController willMoveToParentViewController:nil]; [self.detailsViewController.view removeFromSuperview]; [self.detailsViewController removeFromParentViewController]; but i can't remove them can i? – Ruchit B Apr 11 '16 at 09:53

2 Answers2

1

Ok first, you need to make sure that your detailsViewController property is declared with a strong reference, something like this :

@property (strong, nonatomic) UIViewController *detailsViewController;

This means that as long as the class that declares this property is still in memory, then so will this property be. The 'strong' means that it stays, even when deemed no longer in use.

Now about the creation / removal of this object. The three sections of code you showed there roughly equate to : instantiate / show / hide (and remove).

Instead - just do the instantiate part once, on a method like viewDidLoad, so that, just once, this viewController is created. When showing, just do your animation code. When hiding, do NOT do removeFromSuperview. So it just stays where it is, in memory. It will exist, just off the screen, ready for you to animate it back into memory again.

Anything else not clear, please shout.

Luke Smith
  • 1,218
  • 12
  • 17
  • Hi Luke, you mean to say this for hiding code correct? [self.detailsViewController willMoveToParentViewController:nil]; -- do not remove [self.detailsViewController.view removeFromSuperview]; -- remove [self.detailsViewController removeFromParentViewController]; -- remove – Ruchit B Apr 11 '16 at 09:59
  • Dont: removeFromParentViewController, and dont removeFromSuperview. The calls willMoveTo etc are just to send messages to the child view controller. Think of it like - you are adding it once, and keeping it in memory always, never removing - just moving it off screen with the animation. The move anim is the setFrame part of the animate .. method. – Luke Smith Apr 11 '16 at 10:05
0

Maybe it helps. In your parent class:

        if (self.arrayControllers == nil) {
            self.arrayControllers = [[NSMutableArray alloc] initWithArray: self.navigationController.viewControllers];
        }
        for (UIViewController *vc in self.arrayControllers) {
            if ([vc isKindOfClass:[YourRetainedViewController class]])
                controller = vc;
        }
        if (controller == nil) {
            controller = [[YourRetainedViewController alloc] init];
            [self.arrayControllers addObject:controller];
        }
        [self.navigationController pushViewController:controller animated:YES];

Here:

self. self.arrayControllers - array in ParentViewController that is strong property. YourRetainedViewController - ChildViewController.

So when pop to parent view controller - here is an array that contains an instance of childViewController.

Nike Kov
  • 12,630
  • 8
  • 75
  • 122