initWithNibNameで作成したのUIViewController:バンドル:またはIBOutletを経由して動作が異なります
-
20-09-2019 - |
質問
私は奇妙な行動を発見した、と私はそれが間違って作っていますどのような主張を説明するしたいと思います。
新規に作成しWindowBasedプロジェクトのAppDelegateクラスでは、私は窓にのUIViewControllerを追加しています。
私はそれを二つの異なる方法を行うことができます。
- IBOutletと。 IBにおいて、Iは、単にのUIViewControllerをインスタンス化TestViewControllerに、そのクラスを設定し、(コードのシナリオA)に接続されている。
- コード(シナリオB)とのUIViewControllerを作成します。
- (void)applicationDidFinishLaunching:(UIApplication *)application {
#define USE_IBOUTLET YES // Comment this line to switch to scenario B
#ifdef USE_IBOUTLET
// Scenario A
[window addSubview:theTestViewController.view];
[window makeKeyAndVisible];
#endif
#ifndef USE_IBOUTLET
// Scenario B
TestViewController *theTestViewControllerProgrammatically;
theTestViewControllerProgrammatically = [[TestViewController alloc] initWithNibName:nil bundle:nil];
// According to Apple: "It is a good idea to set the view's frame before adding it to a window.", so let's do it
[theTestViewControllerProgrammatically.view setFrame:[[UIScreen mainScreen] applicationFrame]];
[window addSubview:theTestViewControllerProgrammatically.view];
[window makeKeyAndVisible];
#endif
}
私はIB内のオブジェクトの任意のカスタマイズをしなかったとして、私は両方のシナリオで同じ動作を持つ必要があります。
予想通りシナリオAは、IBOutletを使用して動作します。
しかし、シナリオBは、以下のような問題点があります。
- ビューは右の位置(高、およびステータスバーによって覆われた20個の画素)ではない
。
- ビューが適切にサイズ変更されません(例えば、でコールステータスバーを切り替えてみてください)。
なぜ?
ここでは、プロジェクトのZipアーカイブ問題を再現する場合: HTTP ://dl.dropbox.com/u/1899122/code/ProtoWindowBasedStrangeness.zipする
解決
これは私の長いったらしい答えた後、本当に愚かな音に起こっている、しかし、あなたが抱えている問題は、(プログラム的に)修正するために簡単です。
この行:
[theTestViewController.view setFrame:[[UIScreen mainScreen] applicationFrame]];
実際にする必要があります:
[theTestViewControllerProgrammaticaly setFrame:[[UIScreen mainScreen] applicationFrame]];
あなたはIBによって設定されたVCのためではなく、あなたがプログラム的に作成したもので枠を設定してます。
とにかく - それはすべての私のコメントはまだ適用されていることは注目に値します! (ナビゲーションバーの項目を設定するたとえば、)あなたはIBのコントローラオブジェクトを使用しない場合は、プログラムで行う必要があるでしょういくつかのことはまだあります。
ポール
他のヒント
私はVCのオブジェクトはすべて同じように作成されないことに気づいたのあなたに非常によく似た問題を抱えてきました!ファイルの所有者は、私はプログラム的にインスタンス化ビューコントローラオブジェクトがあるとき、私は、ナビゲーションバーの項目を設定していることだ問題は、私はちょうどそれを行うように見えることはできません。私はIBのコントローラオブジェクトをアーカイブ解除した場合にのみ機能します。
私はあなたのプロジェクトをダウンロードし、それを周りに遊びがあったが、それが起こっているかもしれないものについて、もう少し考えて私を得ました。私は簡単な解決策があれば、私は合理的な答えを提供しますが、わからないことができると思います...
私は何が起こっていると考えていることは、Appleがやや特化されているIBにおけるこれらのコントローラオブジェクトを作成していることです。これは本当かもしれない1つの提案は、IBのコントローラオブジェクトは、いくつかの追加機能を有することができるので、IB VCオブジェクトが属性を持っていることをあなたは、それは私が見ることができるのUIViewControllerクラスには直接対応するプロパティを持っていない設定ができているという非IBのUIViewControllerサブクラスはできませんを活用します。 .xib内のオブジェクトが完了していることを「凍結乾燥」のオブジェクトを考えると、Appleは我々は彼らの彼らのIBバージョンでご覧になるか、使用できないプライベート属性のすべての種類が含まれていること - これは、オブジェクトが初期化されている方法についていくつかの効果を有することができますます。
たとえば、あなたのMainWindow.xib
で、IB VCオブジェクトを選択して、あなたは、このような「NIBからリサイズビュー」として、インスペクタパレットから、それに属性を設定することができます。それは、シナリオBで行うように、あなたがこれを解除チェックした場合は、あなたのアプリケーションを再実行するには、ファイルの所有者の属性からしたときに、それはのUIViewControllerようであっても(この項目をチェックすることができないとしてVCが正確に表示されます)、あなたは、あなたが望む行動を与えるために、ビューコントローラによって行われているものは何でもの利点を取ることができません。
この結果は、あなたがコードの中で、あなたのVCのオブジェクトを初期化するためにTestViewController.xib
を使用する場合、VCのIB特定の属性のどれもが、設定されていないため、沼地、標準のUIViewControllerが作成され、「リサイズ表示のようなので、物事ということですNIB」属性とナビゲーション項目を設定するから自分を実装する必要があります。
私はまだ、私は彼らがinitWithNibName:bundle:nibBundle
を使用してインスタンス化するときIBのビューコントローラが持っている機能を活用する方法を発見していませんでした(私はそれが我々がアクセスすることはできませんすべてのプライベートなものだ推測している)、うまくいけば、これは与えられている場合がありますあなたの出発点...
もちろん、私は完全に間違っている可能性と、誰かが私は完全な馬鹿のように見えるようになります!
ポール
おそらく、そのビューBの場合には、ステータスバーの存在を認識していません。あなたはそれに応じてサイズを変更して、アカウントにステータスバーを取るためにその位置を調整する必要があります。それはのUIViewのフレーム(サイズ)との境界(位置)の特性を変更することによって行われます。