web-dev-qa-db-ja.com

UIViewController -viewDidLoadが呼び出されていません

Cocoaが初めてなので、Interface BuilderUIViewController、および友人といくつかの問題があります。

XibでUIViewControllerが定義されたUIViewサブクラスと、ビューに接続されたコントローラーのビューアウトレットがあります。 xibの「ファイルの所有者」は、myViewcontrollerサブクラスとして設定されます。

この1つのインスタンスでは、コントローラー/ビューを(メインビューコントローラーから)ロードする次のコードは期待どおりに機能しません。

if ( self.myViewController == nil )
{
    self.myViewController = [[MyViewController alloc]
        initWithNibName:@"MyViewController" bundle:nil];
}

[self.navigationController 
    pushViewController:self.myViewController animated:YES];

MyViewControllerのメソッドに、ブレークポイントとログメッセージを配置して、何が起こっているのかを確認しました。

-(id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {

    if (self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]) {
        NSLog(@"initWithNibName\n");
    }

    return self;
}

-(void)viewDidLoad {

    [super viewDidLoad];
    NSLog(@"viewDidLoad\n");
}

期待される結果

-initWithNibNameメソッドと-viewDidLoadメソッドの両方が呼び出され、myViewControllerのビューが表示されます。

観測結果

-initWithNibNameのみが呼び出され、ビューは表示されません。

私は何かを見逃しましたか?誰でもチェックすることをお勧めできますか? (特に、驚くほど不透明なInterface Builderツール)。

31
Justicle

OK問題は:

[self.navigationController pushViewController:myViewController animated:YES];

よく見ると、この場合はself.navigationControllerはnilです-プッシュメッセージはどこにも行きません。

代わりに、私が送信する場合:

[self.view addSubview:self.myViewController.view];

次に、ビューが表示され、-viewDidLoadが呼び出されます。

なぜself.navigationControllerはこのインスタンスでは設定されません-考えられる唯一のことは、selfUIViewControllerではなくUITableViewControllerのサブクラスであるということです(ここで、pushViewControllerコードの由来)。

また、メッセージを静かにnilに送信することを許可するのは悪い考えのように思えますが、 これらの回答 は別の言い方をします。私の質問も参照してください here

最終編集:

以下のコメントの答え、私が実際に求めていた表示機能は次のとおりです(myViewControllerがモーダルである場合)。

[self presentModalViewController:myViewController animated:YES];

有益な回答をありがとう。

14
Justicle

RE:ソリューションが見つかりました!!!!!

確かにそれは実用的なソリューションのようですが、本当のトリックはview.hiddenプロパティをNOに設定することではなく、nibファイルからビューをロードするのはUIViewController's viewメソッドの呼び出しです。 viewメソッドが初めて呼び出されたときにのみ、実際にビューはnibからロードされます。

その意味で、単純な[viewController view]メッセージは、nibファイルからビューを強制的にロードします。

33
Jader Feijo

ソリューションが見つかりました!!!!!

これによりviewDidLoadメソッドの呼び出しが発生するほど無害なものですらあります。

Alloc initWithNibNameの直後にこれを挿入します

viewController.view.hidden = NO; //calls viewDidLoad

_main.storyboard_の_Identity Inspector_にある想定されるViewControllerを、作成したカスタムclassにリンクしていない可能性があります。セグエを介して他のView Controllerからそのコントローラーにナビゲートできるかもしれませんが、viewDidLoad()viewWillAppear()などのいずれも実行されません。

5
Yash Tamakuwala

単に使用する

- (void)viewDidAppear:(BOOL)animated{ 
        [super viewDidAppear:animated];
        //Your Code here
  }

viewDidLoadメソッドの代わりに。

5
Lolloz89

file's Owner(viewControllerサブクラス)のビューアウトレットが実際のビュー(つまり、UIの構築に使用する画面に表示される480X320キャンバス)に接続されていることを確認してください

4
zpesk

振り返ってみると、もう少し明白な別の理由:if viewController.viewがコードで設定されている場合、viewDidLoadイベントはトリガーされません。

3
nmr

私には大文字の問題のように見えます。 pushViewControllerの呼び出しで、プロパティMyViewControllerの代わりにクラスmyViewControllerを参照しています。

3
slf

実行ログでエラーを確認してください。ほぼ確実に、NIBはロードされておらず、その結果にエラーがあるはずです。その原因として最も可能性が高いのは、バンドルに入れられなかったことです。 「リソースのコピー」ビルドフェーズを見て、XIBが実際にコピーされていることを確認します。シミュレータ用にビルドし、ビルドディレクトリに移動して、NIBが.appバンドルに含まれていることを確認します。

2
Rob Napier