SettingsViewController

SettingsViewController

我正在尝试制作一个应用程序,第一步是创建viewControllers并将其链接。我知道我可以使用情节提要和告示板来做到这一点,但我想以传统的方式来实现-通过编码即

它包含4个视图控制器

-MainViewController
-SettingsViewController
-RulesViewController

这三个视图控制器使用ContainerViewController(第4个viewController)(我编写的自定义容器)进行管理。 currentSubViewController跟踪当前正在显示的viewController
@implementation ContainerViewController
{
     UIViewController * currentSubViewController;
}

所有三个viewController都是从.nib创建的
  • 主页有2个按钮“设置”和“规则”
  • 设置具有2个按钮“Main”和“Rules”
  • 规则有2个按钮“Main”和“Settings”

  • 在启动时:

    将currentSubViewController设置为MainViewController的实例,然后
    [container addChildViewController: currentSubViewController]
    

    使容器成为currentSubViewController的父级。

    并且主页显示没有任何问题

    在按下“设置按钮”启动后

    调用MainViweController中的IBAction
    - (IBAction)onSettings:(id)sender {
            if ([self parentViewController]) {
                 [(ContainerViewController*)[self parentViewController showViewControllerWithName:@"settings"];
    }
    }
    

    然后调用showViewControllerWithNameContainerViewController
    - (void) showViewControllerWithName:(NSString*)vctype
    {
        UIViewController * toVC = [ViewControllerFactory getViewControllerOfType:vctype]; // viewController factory returns the appropriate viewController i.e either MainViewController or SettingsViewController or  RulesViewController
    
        toVC.view.frame = containerView.bounds;
        toVC.view.autoresizingMask = containerView.autoresizingMask;
    
        [currentSubViewController willMoveToParentViewController:nil];
    
        [self addChildViewController:toVC];
    
        [self transitionFromViewController:currentSubViewController
                      toViewController:toVC duration:1.0 options:UIViewAnimationOptionCurveLinear animations:^{} completion:^(BOOL finished){
                          [currentSubViewController removeFromParentViewController];
                          [toVC didMoveToParentViewController:self];
    
                      }];
        currentSubViewController = toVC;
    
    // I checked here toVC has a parentViewController set to ContainerViewController
    }
    

    SettingsViewController 显示

    按下SettingsViewController上的“主”按钮

    在SettingsMainController中的IBACtion被称为
     - (IBAction)onMain:(id)sender {
        if ([self parentViewController]) { // parentViewController is nil here
            [(ContainerViewController*)[self parentViewController] showViewControllerWithName:@"root"];
    
        }
     }
    

    但是ParentViewController在这里为零,因此未显示任何内容。在上一步中,SettingsViewController是来自函数调用showViewControllerWithName的toVC。

    showViewControllerWithName()OnMain()之间的某个位置,parentViewController被设置为nil。我检查直到viewDidAppear和parentViewController都为零为止。

    我的问题是
  • 哪里parentViewController设置为nil?
  • 要调试此问题,我想知道viewDidAppear后会调用哪些其他内部函数
  • 使用工厂类创建新的UIViewControllers会产生问题吗?
  • 尽管我在调试器中检查了内存地址是否与相同,但
  • 正在创建实例且实例显示为不同?

    我无法解决此问题。我尝试了一种非常hacky的方式,即在派生类中跟踪父级,即使transitionFromViewController:引发异常,也表明两个视图控制器应具有同一父级。

    我被困在这里将近两天了。我将非常感谢您的帮助。

    最佳答案

    好吧,我终于能够使它起作用。让我再次简要地解释这个问题

    -> ContainerViewController显示MainViewController,当您检查MainViewController.ParentController时,它实际上是ContainerViewController
    -> ContainerViewController使用以下功能从MainViewController转换为SettingsViewController

      (void) showViewControllerWithName:(NSString*)vctype
      {
         UIViewController * toVC = [ViewControllerFactory getViewControllerOfType:vctype];
        toVC.view.frame = containerView.bounds;
        toVC.view.autoresizingMask = containerView.autoresizingMask;
    
        [currentSubViewController willMoveToParentViewController:nil];
    
        [self addChildViewController:toVC];
    
        [self transitionFromViewController:currentSubViewController
                  toViewController:toVC duration:1.0 options:UIViewAnimationOptionCurveLinear animations:^{} completion:^(BOOL finished){
                      [currentSubViewController removeFromParentViewController];
                      [toVC didMoveToParentViewController:self];
    
                  }];
        currentSubViewController = toVC;
    
    
    }
    

    ->过渡后SettingsViewController.parentViewController为nil

    以下是解决方法:
               animations:^{} completion:^(BOOL finished){
                      [currentSubViewController removeFromParentViewController];
                      [toVC didMoveToParentViewController:self];
    
                  }];
    
        currentSubViewController = toVC;
    

    更改为
               animations:^{} completion:^(BOOL finished){
    
                  }];
        [currentSubViewController removeFromParentViewController];
        [toVC didMoveToParentViewController:self];
        currentSubViewController = toVC;
    

    现在SettingsViewController有一个父级。

    好吧,如果有人可以解释到底发生了什么,那将是很棒的。

  • 10-07 20:43