1

我有一个 UINavigationController 类(并链接到情节提要“mainNavCont”),其中包含:

- (void)viewDidLoad
{
    [super viewDidLoad];
    NSLog(@"init"); 
}

- (void)viewDidAppear:(BOOL)animated
{
    NSLog(@"View Appeared");
    UINavigationController *selfNavController = [self navigationController];
    [selfNavController performSegueWithIdentifier:@"rootToPortSeg" sender:self];
}

故事板中有一个标识符为“rootToPortSeg”的segue,类型为“push”,它链接到一个名为“portViewCont”的UIViewController。在该类中有以下内容:

- (void)viewDidLoad
{
    [super viewDidLoad];
    NSLog(@"I am the port");
}

一切都编译得很好,我在 Xcode 中没有错误。但是 portViewCont UIViewController 从不加载或显示或任何东西。我还是 iOS 的新手,对于我的生活,我无法弄清楚我做错了什么。我在控制台中得到“init”和“View Appeared”,但没有得到“I am the port”,谢谢!

在此处输入图像描述

4

3 回答 3

1

我喜欢 rdelmar 进行分析的地方,但是正如您所看到的,您似乎无法从导航控制器本身执行 push segue(这是有道理的)。但是,看起来你可以instantiateViewControllerWithIdentifier,那么你可以pushViewController从导航控制器中得到它。因此,如果子类UINavigationControllerviewDidLoad类似的:

- (void)viewDidLoad
{
    [super viewDidLoad];

    // this is the storyboard identifier for the portrait view controller

    UIViewController *controller = [self.storyboard instantiateViewControllerWithIdentifier:@"portrait"];

    // now you can push to it

    [self pushViewController:controller animated:NO];
}

然后,纵向视图被加载,你会看到它@"I am the port",你会看到你在 Interface Builder 中为那个视图添加的控件,等等。


更新:

我不得不承认,虽然上述技术有效,但我想知道这是否是最好的方法。具体来说,查看您的故事板,我推断您的目标是拥有一个用于纵向的视图控制器和另一个用于横向的视图控制器。如果这就是您想要做的,您可以使用 Apple 在其视图控制器编程指南创建备用景观界面部分中列出的技术。

也许您可以描述为什么要使用导航控制器来执行此操作,而实际上它并没有真正设计用于处理该问题。它实际上更适合处理视图控制器的推送和弹出,而不是在不同的视图控制器之间进行选择。我认为你可以让它工作,但我想知道View Controller Programming Guide中描述的技术是否更合适。但也许你有一些功能需求在你的故事板中并没有立即显现出来。

于 2012-10-06T03:51:32.880 回答
1

在对这个问题进行了更多思考之后,我认为最好的方法是使用自定义容器控制器,其中包含 PortraitController 和 LandscapeController 作为其子级。

在下面的代码中,我在容器控制器的 init 方法中实例化了 2 个子控制器,并具有指向它们的强大属性,因此在来回切换时,您将访问相同的实例。我在启动时检查设备方向的方法中设置了初始视图控制器,然后在回调 UIDeviceOrientationDidChangeNotification 时切换控制器。最后,实际的动画切换是使用 transitionFromViewController:toViewController:duration:options:animations:completion: 方法完成的。

#import "ContainerController.h"
#import "LandscapeController.h"
#import "PortraitController.h"

@implementation ContainerController

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {
    if (self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]) {
        self.portCont = [[PortraitController alloc]initWithNibName:@"PortraitController" bundle:nil];
        self.landCont = [[LandscapeController alloc] initWithNibName:@"LandscapeController" bundle:nil];
        [self performSelectorOnMainThread:@selector(checkLaunchOrientation) withObject:nil waitUntilDone:NO];
    }
    return self;
}


-(void)checkLaunchOrientation {
    if ([[UIDevice currentDevice] orientation] !=0) {

        if (UIDevice.currentDevice.orientation == UIDeviceOrientationPortrait | UIDevice.currentDevice.orientation == UIDeviceOrientationPortraitUpsideDown){
            if ([self.currentController class] != [self.portCont class] ) {
                self.currentController = self.portCont;
                [self addChildViewController:self.portCont];
                [self.view addSubview:self.portCont.view];
            }
        }else if (UIDevice.currentDevice.orientation == UIDeviceOrientationLandscapeLeft | UIDevice.currentDevice.orientation == UIDeviceOrientationLandscapeRight){
            if ([self.currentController class] != [self.landCont class] ) {
                self.currentController = self.landCont;
                [self addChildViewController:self.landCont];
                [self.view addSubview:self.landCont.view];
            }
        }
        [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(orientationChanged:) name:UIDeviceOrientationDidChangeNotification object:nil];
    }else{
        [self checkLaunchOrientation];
    }
}


-(void)orientationChanged:(NSNotification *) aNote {
    if (UIDevice.currentDevice.orientation == UIDeviceOrientationPortrait | UIDevice.currentDevice.orientation == UIDeviceOrientationPortraitUpsideDown){
        if ([self.currentController class] != [self.portCont class] ) {
            [self addChildViewController:self.portCont];
            [self moveToNewController:self.portCont];
        }
    }else if (UIDevice.currentDevice.orientation == UIDeviceOrientationLandscapeLeft | UIDevice.currentDevice.orientation == UIDeviceOrientationLandscapeRight){
        if ([self.currentController class] != [self.landCont class] ) {
            [self addChildViewController:self.landCont];
            [self moveToNewController:self.landCont];
        }
    }
}


-(void)moveToNewController:(id) newController {
    [self.currentController willMoveToParentViewController:nil];
    [self transitionFromViewController:self.currentController toViewController:newController duration:.6 options:UIViewAnimationOptionTransitionFlipFromLeft animations:^{}
        completion:^(BOOL finished) {
        [self.currentController removeFromParentViewController];
        [newController didMoveToParentViewController:self];
        self.currentController = newController;
    }];
}


-(BOOL)shouldAutorotate {
    return YES;
}

- (NSUInteger)supportedInterfaceOrientations {
    return UIInterfaceOrientationMaskAll;
}
于 2012-10-10T00:01:57.380 回答
0

如果我正确理解您的设置,则您发布的代码位于您的 MainNavCont 控制器中。如果是这样,我不明白你在用这条线做什么:

UINavigationController *selfNavController = [self navigationController];

您的代码所在的类导航控制器,您应该只在 performSegue: 方法中使用 self:

[self performSegueWithIdentifier:@"rootToPortSeg" sender:self];
于 2012-10-06T03:22:13.330 回答