Ios 具有3个子级的容器ViewController必须有一个常见的父视图控制器错误

Ios 具有3个子级的容器ViewController必须有一个常见的父视图控制器错误,ios,iphone,objective-c,uiviewcontroller,Ios,Iphone,Objective C,Uiviewcontroller,我有一个有3个孩子的VC家长-设置、地点和日记 设置、位置和日志都可以通过iActions根据各自的按钮进行访问 当我在地点和日记之间穿梭时,一切都很好。当我单击“设置”时,它会工作,但当我单击“返回位置”或“日记”时,我会得到一个可怕的消息,这肯定是一个常见的父视图控制器错误。有趣的是,例外情况是日记和位置VC不共享同一个父对象,即使在这种情况下,我在设置和日记或位置之间单击 m.物业 @interface LPMainContentViewController () @property (

我有一个有3个孩子的VC家长-设置、地点和日记

设置、位置和日志都可以通过iActions根据各自的按钮进行访问

当我在地点和日记之间穿梭时,一切都很好。当我单击“设置”时,它会工作,但当我单击“返回位置”或“日记”时,我会得到一个可怕的消息,这肯定是一个常见的父视图控制器错误。有趣的是,例外情况是日记和位置VC不共享同一个父对象,即使在这种情况下,我在设置和日记或位置之间单击

m.物业

@interface LPMainContentViewController ()
@property (weak, nonatomic) IBOutlet UIView *containerView;

@property (weak, nonatomic) IBOutlet UIButton *locationButton;
@property (weak, nonatomic) IBOutlet UIButton *diaryButton;
@property (weak, nonatomic) IBOutlet UIButton *settingsButton;


@property (strong, nonatomic) UIViewController *locationViewController;
@property (strong, nonatomic) UIViewController *diaryViewController;
@property (strong, nonatomic) UIViewController *settingsController;

- (IBAction)goToLocationView:(UIButton *)sender;
- (IBAction)goToDiaryView:(UIButton *)sender;
- (IBAction)goToSettings:(UIButton *)sender;

@end
我在代码中使用if语句来确定转换方法的前一个子VC,并将按钮上的enabled设置为YES或NO

    - (IBAction)goToLocationView:(UIButton *)sender {
    if ([_diaryViewController isViewLoaded]){
        [self cycleFromViewController:_diaryViewController toViewController:_locationViewController];
        _locationButton.enabled = NO;
        _diaryButton.enabled = YES;
    }
    else if ([_settingsController isViewLoaded]){
        [self cycleFromViewController:_settingsController toViewController:_locationViewController];
        _locationButton.enabled = NO;
        _settingsButton.enabled = YES;
    }
}

- (IBAction)goToDiaryView:(UIButton *)sender {

    if ([_locationViewController isViewLoaded]){
        [self cycleFromViewController:_locationViewController toViewController:_diaryViewController];
        _locationButton.enabled = YES;
        _diaryButton.enabled = NO;
    }
    else if ([_settingsController isViewLoaded]){
        [self cycleFromViewController:_settingsController toViewController:_diaryViewController];
        _diaryButton.enabled = NO;
        _settingsButton.enabled = YES;
    }
}

- (IBAction)goToSettings:(UIButton *)sender {
    if ([_locationViewController isViewLoaded]){
        [self cycleFromViewController:_locationViewController toViewController:_settingsController];
        _locationButton.enabled = YES;
        _settingsButton.enabled = NO;
    }
    else if ([_diaryViewController isViewLoaded]){
        [self cycleFromViewController:_diaryViewController toViewController:_settingsController];
        _diaryButton.enabled = YES;
        _settingsButton.enabled = NO;
    }
}
这是直接从Apple文档中提取的过渡方法

- (void) cycleFromViewController: (UIViewController*) oldVC

                toViewController: (UIViewController*) newVC

{

    [oldVC willMoveToParentViewController:nil];
    [self addChildViewController:newVC];




    newVC.view.frame = _containerView.bounds;

    CGRect endFrame = _containerView.bounds;



    [self transitionFromViewController: oldVC toViewController: newVC

                              duration: 0.0 options:0

                            animations:^{

                                newVC.view.frame = oldVC.view.frame;

                                oldVC.view.frame = endFrame;

                            }

                            completion:^(BOOL finished) {

                                [oldVC removeFromParentViewController];

                                [newVC didMoveToParentViewController:self];


                            }];

}

isViewLoaded
是错误的检查方法。视图将加载一次,然后继续加载,因此在几个周期后,您可能选择了错误的“当前”视图控制器。使用另一个属性来保存当前视图控制器,它将简化代码并实际工作:

@property (weak, nonatomic) UIViewController *currentViewController;
当您第一次设置容器视图控制器时,需要将其设置为初始子视图控制器

然后,将
goToXX
方法更改为如下所示:

- (IBAction)goToDiaryView:(UIButton *)sender {

    self.settingsButton.enabled = YES;
    self.locationButton.enabled = YES;
    self.diaryButton.enabled = NO;
    [self cycleFromViewController:self.currentViewController toViewController:self.diaryViewController];
}
最后,在
循环
方法中,确保在转换的完成块中更新此属性:

completion:^(BOOL finished) {
    [oldVC removeFromParentViewController];
    [newVC didMoveToParentViewController:self];
    self.currentViewController = newVC;
}];

请注意,使用属性比使用
\u instanceVariables
更安全。这就是他们在那里的目的

您能否澄清“使用另一个属性来保存当前视图控制器”的含义?此外,单击“设置”时会出现问题,在位置和日记之间切换不会导致任何问题,因此可以备份您所说的内容。我的意思是,在容器视图控制器中,有一个名为“currentViewController”或类似的属性,该属性包含位于顶部的属性。在切换或添加视图控制器时设置此选项,并将其用作转换中的“oldVC”。谢谢,它可以工作。如果我错了,请纠正我,但之所以这样做是因为containerViewController是视图继承者权限中的一个,您只需切换它的值,这样就不会出现错误,因为它总是containerViewController?您的意思是“currentViewController”,但是的。