如何在移回父级后保留子视图控制器(容器实现)?

问题描述:

我需要保留子视图控制器解除后将其移回需要时没有额外的子视图控制器处理。我曾尝试使用下面的链接实现它:如何在移回父级后保留子视图控制器(容器实现)?

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

How does View Controller Containment work in iOS 5?

这些链接(以及类似的其他人)都将成为子视图控制器或贬,但不是“保留它”的目的。请在下面找到我的代码:

/* 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]; 
}]; 

,如果我需要“刷卡上再次父”把孩子控制,我不得不再次经历的整个过程。我需要做的只是“让孩子在滑动手势上”过程,而不是再次实例化,因为实例化将在子控制器中处理数据(耗时)。

我是iOS应用程序编程的noob,所以如果这是一个明显的问题,请耐心等待。

+0

如何声明'self.detailsViewController'?它应该是'强'。 – Cyrille

+0

@property(强,非原子)DetailsViewController * detailsViewController; 我认为这个问题是在这几行: [self.detailsViewController willMoveToParentViewController:nil]; [self.detailsViewController.view removeFromSuperview]; [self.detailsViewController removeFromParentViewController]; 但我不能删除它们可以吗? –

好吧首先,你需要确保你的detailsViewController属性声明具有较强的参考,像这样:

@property (strong, nonatomic) UIViewController *detailsViewController; 

这意味着只要声明该属性类是仍在内存,那么这个属性也会如此。 “强”意味着它即使在不再被使用的情况下仍然存在。

现在创建/删除此对象。你在那里显示的三段代码大致等同于:实例化/显示/隐藏(和删除)。

取而代之 - 只需在viewDidLoad之类的方法上实例化一次部件,以便只创建一次viewController。展示时,只需执行您的动画代码即可。隐藏时,不要从removeSuperview中删除。所以它只是留在原地,在记忆中。它将存在,就在屏幕之外,准备好让它再次将其动画回忆。

还有什么不清楚的,请大声点。

+0

嗨卢克,你的意思是说这个隐藏代码是正确的? [self.detailsViewController willMoveToParentViewController:nil]; - 不要删除 [self.detailsViewController.view removeFromSuperview]; - 删除 [self.detailsViewController removeFromParentViewController]; - 删除 –

+0

不要:removeFromParentViewController,并且不要removeFromSuperview。调用willMoveTo等只是发送消息到子视图控制器。想一想 - 你正在添加一次,并始终保存在内存中,永远不要移除 - 只需将它从动画中移出屏幕即可。移动动画是动画..方法的setFrame部分。 –

+0

谢谢卢克。这很好。 –

也许它有帮助。 在你的父类:

 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]; 

这里:

self. self.arrayControllers - 数组中ParentViewController,是一个强大性能。 YourRetainedViewController - ChildViewController。

所以当弹出到父视图控制器 - 这里是一个数组,其中包含childViewController的一个实例。

+0

谢谢你的回答尼克。但卢克已经给了我一个满意的:) –