3

奇妙な動作を見つけました。どの主張が間違っているかを説明してもらいたいです。

新しく作成した WindowBased プロジェクトの AppDelegate クラスで、ウィンドウに UIViewController を追加しています。
私はそれを 2 つの異なる方法で行うことができます:
- IBOutlet を使用します。IB では、単純に UIViewController をインスタンス化し、そのクラスを TestViewController に設定して接続しました (コードのシナリオ A)。
- コードを使用して UIViewController を作成する (シナリオ B)。

    - (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 には次の問題があり
ます。
- ビューのサイズが適切に変更されない (たとえば、通話中ステータス バーを切り替えようとする)

なんで?

問題を再現したい場合は、プロジェクトの zip アーカイブをこちらからダウンロードしてください: http://dl.dropbox.com/u/1899122/code/ProtoWindowBasedStrangeness.zip

4

3 に答える 3

2

私の長々とした回答の後で、これは本当にばかげているように聞こえるでしょうが、あなたが抱えている問題は (プログラムで) 簡単に修正できます。

この行:

[theTestViewController.view setFrame:[[UIScreen mainScreen] applicationFrame]];

実際には次のようになります。

[theTestViewControllerProgrammaticaly setFrame:[[UIScreen mainScreen] applicationFrame]];

プログラムで作成したものではなく、IB によって設定された VC のフレームを設定していました。

とにかく、私のコメントはすべて適用されることに注意してください。IB のコントローラー オブジェクトを使用しない場合は、プログラムで行う必要があることがいくつかあります (たとえば、ナビゲーション バー項目の設定)。

ポール

于 2010-02-18T20:17:25.447 に答える
1

VC オブジェクトがすべて同じように作成されていないことに気付いたという点で、私はあなたと非常によく似た問題を抱えています。私が抱えている問題は、ナビゲーションバーの項目を設定することです.File's Ownerがプログラムでインスタンス化するView Controllerオブジェクトである場合、それを行うことができないようです. IB のコントローラー オブジェクトを解凍した場合にのみ機能します。

私はあなたのプロジェクトをダウンロードして遊んでみたところ、何が起こっているのかについてもう少し考えさせられました. 合理的な答えを提供できると思いますが、簡単な解決策があるかどうかはわかりません...

私が信じているのは、Apple が IB でこれらのコントローラー オブジェクトを作成したことで、これらは少し専門化されたものになっています。これが真実である可能性がある1つの提案は、IB VCオブジェクトには、私が見ることができるUIViewControllerクラスに直接対応するプロパティを持たない設定可能な属性があるため、IBのコントローラーオブジェクトには、非IB UIViewControllerサブクラスができないいくつかの追加機能がある可能性があるということですを利用します。.xib 内のオブジェクトが完全な「フリーズドライ」オブジェクトであることを考えると、Apple は、それらの IB バージョンでは表示または使用できないすべての種類のプライベート属性を含めている可能性があります。これは、オブジェクトの初期化方法に何らかの影響を与える可能性があります。 .

たとえば、 でMainWindow.xibIB VC オブジェクトを選択すると、インスペクタ パレットから「NIB からビューのサイズを変更」などの属性を設定できます。これをオフにしてアプリを再実行すると、シナリオ B とまったく同じように VC が表示されます。ファイルの所有者属性からこの項目を確認できないため (UIViewController としてであっても) )、View Controllerによって行われていることを利用して、必要な動作を提供することはできません.

この結果TestViewController.xib、コードで VC オブジェクトを初期化するために を使用すると、VC の IB 固有の属性が設定されないため、ボグ標準の UIViewController が作成され、「Resize View From NIB」属性のようなものになります。ナビゲーション項目の設定は自分で実装する必要があります。

IB のビュー コントローラーを使用してインスタンス化するときに、IB のビュー コントローラーが持つ機能を利用する方法をまだ見つけていませんinitWithNibName:bundle:nibBundle(アクセスできないすべてのプライベートなものだと思います)。 ...

もちろん、私は完全に間違っている可能性があり、誰かが私を完全な馬鹿に見せるでしょう!

ポール

于 2010-02-14T19:35:27.533 に答える
0

おそらくケース B では、そのビューはステータス バーの存在を認識していません。それに応じてサイズを変更し、ステータス バーを考慮して位置を調整する必要があります。これは、UIView のフレーム (サイズ) と境界 (場所) プロパティを変更することによって行われます。

于 2010-02-13T12:50:11.720 に答える