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」、タイプが「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 が分析を行っているところが気に入りましたが、ご覧のとおり、ナビゲーション コントローラー自体からプッシュ セグエを実行できないようです (これは理にかなっています)。しかし、それはできるように見えますが、ナビゲーションコントローラーから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 が提示しているテクニックを使用できます。

ナビゲーション コントローラーが実際にはそれを処理するように設計されていないのに、なぜこれを行うためにナビゲーション コントローラーを使用しているのかを説明できるかもしれません。異なるView Controllerから選択するためではなく、View Controllerのプッシュとポップを処理することを目的としています。あなたはそれを機能させることができると思いますが、ビュー コントローラー プログラミング ガイドで説明されている手法の方が適切ではないでしょうか。しかし、ストーリーボードからすぐにはわからない機能要件があるかもしれません。

于 2012-10-06T03:51:32.880 に答える
1

この問題についてもう少し考えた結果、ポートレート コントローラーとランドスケープ コントローラーを子として持つカスタム コンテナー コントローラーを使用するのが最善の方法だと思います。

次のコードでは、コンテナー コントローラーの 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 に答える