具有3个子项的Container ViewController必须具有公共父视图控制器错误

时间:2014-07-23 08:08:35

标签: ios iphone objective-c uiviewcontroller

我有一个有三个孩子的父VC - 设置,位置和日记。

设置,位置&日记可以通过IBActions根据各自的按钮进行访问。

UIButtons in storyboard

当我在位置和日记之间走的时候,一切都很好。当我单击“设置”时,它可以正常工作,但是当我单击“位置”或“日记”时,我会发现可怕的必须有一个共同的父视图控制器错误。有趣的是,除非在这种情况下我在设置和日记或位置之间点击,否则日记和位置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,并将按钮上的启用设置为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];


                            }];

}

1 个答案:

答案 0 :(得分:2)

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

最后,在您的cycle方法中,请确保在转换的完成块中更新此属性:

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

请注意,使用您的属性而不是_instanceVariables更安全。这就是他们的目的。