【新サービス告知】いつでもどこでもイベントを開催できる。スマホのWebカメラを利用したVRイベントスペースサービス(Meetatcube.com)
↑クリックして拡大
↑クリックして拡大
↑クリックして拡大
↑クリックして拡大

頭痛が減ったので共有です!

rebuild.fmを応援しています!

HOME > UIWindowを理解してMain.storyboardを削除してみる

UIWindow

iOS開発でよく耳にしていたUIWindowクラス。正直私はあまり理解していませんでしたのでこの記事にて 理解を深めたいと思います。

UIWindowサンプル画像

UIWindowのクラス階層

NSObject

UIResponder

UIView

UIWindow


参考:iOS開発におけるウィンドウ「UIWindow」の知られざる活用方法とは? #iOS
参考:UIKit Framework Reference UIWindow Class Reference
参考:026 UIWindowの表示
参考:How to set UIWindow property in Swift

どこで利用されているか

例えばSingle View Applicationで新規プロジェクトを作成した場合。ひっそりと一行windowの宣言がAppDelegate.swiftに記載されているだけです。つまり、 開発者もあまり気にしないでUIWindowを使っているようです。


@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {

    var window: UIWindow?

    func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
        // Override point for customization after application launch.
        return true
    }
    ...
    
}

では、消してコンパイルするとどうなるかやってみます。


@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
    func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
        // Override point for customization after application launch.
        return true
    }
    ...
    
}

あれ、ランタイムエラーがでるかと思いましたがコンパイルは成功。ただしアプリ起動時にエミュレーターの画面は真っ黒でログには以下のようなエラーがでました


2015-01-23 07:20:27.159 
 The app delegate must implement the window property if it wants to use a main storyboard file.

AppDelagateクラスにはかならずwindowをプロパティにセットしてね(もしstoryboradを使うんであれば)。 AppDelegate.swfitのクラス宣言には、UIApplicationDelegateプロトコルが記載されていますが、 おそらくこのクラス内部でインターフェース的にルールに縛られているようです。UIApplicationDelegateの中身を見てみます。


protocol UIApplicationDelegate : NSObjectProtocol {
    ...
        optional var window: UIWindow? { get set }
    ...
}

宣言されていました。ただ、optionalの記載があるのでコンパイルはできたのかと思われます。先ほどのエラーメッセージによればstoryboardを使わないのであればUIWindowを消しても良さそうなのかな、、、調査してみます

以下の記事によると、storyboardを削除してUIWindowを実装することはできそうです
参考:How do I create a new Swift project without using Storyboards?

Main.storyboardを削除して、以下に修正してコンパイルしてみます


@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {

    var window: UIWindow?

    func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
        
        self.window = UIWindow(frame: UIScreen.mainScreen().bounds)
        self.window!.backgroundColor = UIColor.whiteColor()
        self.window!.makeKeyAndVisible()
        
        return true
    }
    ...
    
} 

画面が真っ暗にはらず設定した白背景が正しく表示されました。ただし以下ログがコンソールに表示されていました。


2015-01-23 07:36:37.957 
Application windows are expected to have a root view controller at the end of application launch

アプリは起動時にルートビューコントラーを保有している必要があるとの記載がありました。UIWindowの宣言とmakeKeyAndVisibleだけでは 足りないようですので、もうすこし調査します。

解決しました。エラーメッセージにあったようにrootViewControllerとしてセットしていなかった為でした


@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {

    var window: UIWindow?

    func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
        
        self.window = UIWindow(frame: UIScreen.mainScreen().bounds)
        self.window!.rootViewController = ViewController()
        self.window!.backgroundColor = UIColor.whiteColor()
        self.window!.makeKeyAndVisible()
        
        return true
    }
    ...
    
} 

これでViewControllerクラスが自動で生成されrootViewとしてセットされます。

例えば以下のように、独自に作成したUIViewControllerをプロトコルに持っている SwiftSalaryManViewControllerを宣言させることもできます。


@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {

    var window: UIWindow?

    func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
        
        self.window = UIWindow(frame: UIScreen.mainScreen().bounds)
        self.window!.rootViewController = SwiftSalaryManViewController()
        self.window!.backgroundColor = UIColor.whiteColor()
        self.window!.makeKeyAndVisible()
        
        return true
    }
    ...
    
} 

まとめ

UIWindowは特に気にしなくても良い。のかな、、、storyboardを消さなくても開発はできますので、、、、ただ、スッキリAppDelegate等の起動まわりを 理解は深まったのでモヤモヤがなくなってUIWindowの呪縛から逃れた気持ちになりました。微力でもお役に立てていれば嬉しいです。

↓こんな記事もありますよ!


2021-04-22 14:54:53

かっこいいカルーセル厳選3点!WebGLを使った渋い画像スライダー。

昨日カッコいいスライダーを探す旅にでていました。 よく使われるswiper など、シンプルで使いやすくデザインも良いのですが、何かもの足りない、、、。 そこで調べていくと、webglを使...

2021-04-20 14:46:43

Twillioとは何??skywayとは何が違うのか。webrtcを使う際に判断する情報。

先日webrtc開発で「twillio」といった名前を聞きました。 以前自分でskywayを使ってwebrtcを試していた際に調べた時には、無かったような気もするんだけと、KDDIが絡んでいる...

2021-04-19 13:58:21

先日久々にアップデートした妊娠週刊パパのAndroid版も。アカウント移管したいんだけど、注文ID見当たらないよ。

先日の妊娠、出産、育児関連のアプリ「妊娠週刊パパ」をAndroid studioで再リリースしようと思ってるんだけど、コンパイル失敗してエミュレータで動かせない。 多分sdkとかapiのバージ...
このエントリーをはてなブックマークに追加
右側のFacebookのLikeをクリック頂けると記事更新の際に通知されますので宜しければご利用下さい!