UIWindow と UIWindowLevel の理解

UIWindow は特殊な UIView のサブクラスであり、アプリケーションのビュー階層における最上位のコンテナとして機能します。通常、アプリには単一の UIWindow が存在しますが、複数のウィンドウを手動で作成して追加することも可能です。UIWindow の主な役割は以下の通りです:

  1. アプリが表示する全てのビューを包含するコンテナとしての機能
  2. タッチイベントをビューや他のオブジェクトへ伝達する役割
  3. UIViewController との連携による端末回転のサポート

ビューを UIWindow に追加する方法は主に二つあります:

addSubview による追加

直接 addSubview メソッドを使用してビューを追加する方法です。この場合、ウィンドウはビューのライフサイクル管理を自動的に行わないため、対応する UIViewController の生存管理を開発者が責任を持って行う必要があります。

rootViewController プロパティの利用

UIWindow の rootViewController プロパティにビューコントローラを設定すると、ウィンドウが自動的にそのビューを自身に追加し、ビューコントローラのライフサイクルを管理します。これにより、早期解放のリスクを軽減できます。

ウィンドウレベル(UIWindowLevel)

UIWindow は表示時に UIWindowLevel の値に基づいて階層的に配置されます。高いレベルを持つウィンドウは、低いレベルのウィンドウの前面に表示されます。システムで定義されている主なレベル定数は以下の通りです:

const UIWindowLevel UIWindowLevelNormal; const UIWindowLevel UIWindowLevelAlert; const UIWindowLevel UIWindowLevelStatusBar; typedef CGFloat UIWindowLevel;

実際のレベル値を出力すると以下のようになります:

Normal window level: 0.000000
Alert window level: 2000.000000
Status window level: 1000.000000

この値から、各レベルの大小関係は Normal < StatusBar < Alert であることが確認できます。以下の実装例で動作を検証します:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { // プライマリウィンドウ self.mainWindow = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds]; self.mainWindow.backgroundColor = [UIColor systemYellowColor]; [self.mainWindow makeKeyAndVisible]; // 標準レベルウィンドウ UIWindow *standardWindow = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds]; standardWindow.backgroundColor = [UIColor systemGreenColor]; standardWindow.windowLevel = UIWindowLevelNormal; [standardWindow makeKeyAndVisible]; // アラートレベルウィンドウ CGRect alertFrame = CGRectMake(40, 40, [UIScreen mainScreen].bounds.size.width - 80, [UIScreen mainScreen].bounds.size.height - 80); UIWindow *alertWindow = [[UIWindow alloc] initWithFrame:alertFrame]; alertWindow.windowLevel = UIWindowLevelAlert; alertWindow.backgroundColor = [UIColor systemRedColor]; [alertWindow makeKeyAndVisible]; // ステータスバーレベルウィンドウ UIWindow *statusWindow = [[UIWindow alloc] initWithFrame:CGRectMake(0, 40, 320, 25)]; statusWindow.windowLevel = UIWindowLevelStatusBar; statusWindow.backgroundColor = [UIColor systemGrayColor]; [statusWindow makeKeyAndVisible]; return YES; }

この実装から分かる重要な特性:

  1. 同じレベルのウィンドウが複数ある場合、最初に makeKeyAndVisible されたもののみが表示される
  2. 表示順序は KeyWindow ステータスではなくウィンドウレベルによって決定される

同レベルで後から追加したウィンドウを表示させるには、ウィンドウレベルを微調整します(例:standardWindow.windowLevel = UIWindowLevelNormal + 1)。

タグ: UIWindow UIWindowLevel UIKit iOS開発

7月11日 20:08 投稿