performSegueWithIdentifier不实例化UIViewController

时间:2012-10-06 02:10:25

标签: objective-c ios uinavigationcontroller

我有一类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”,但不是“我是端口”,谢谢!

enter image description here

3 个答案:

答案 0 :(得分:1)

我喜欢rdelmar进行分析的地方,但正如您所看到的,看起来您无法从导航控制器本身执行推送(这很有意义)。但是,看起来你可以instantiateViewControllerWithIdentifier,那么你可以从导航控制器中pushViewController那么好。因此,如果子类UINavigationController具有viewDidLoad之类:

- (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在Creating an Alternate Landscape Interface部分的 View Controller Programming Guide 中列出的技术。

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

答案 1 :(得分:1)

在考虑了这个问题之后,我认为最好的方法是使用带有portraitController和landscapeController的自定义容器控制器作为其子项。

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

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

答案 2 :(得分:0)

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

UINavigationController *selfNavController = [self navigationController];

你的代码在中的类是导航控制器,你应该在performSegue:method中使用self:

[self performSegueWithIdentifier:@"rootToPortSeg" sender:self];