HOME > UIWindowを理解してMain.storyboardを削除してみる
iOS開発でよく耳にしていた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-05-14 14:21:41 | WatchOSのwatchconnectivityのFiletransferの落とし穴。と、避け方。
AppleWatch 実機だと成功するんだけど、シュミレーターだと失敗するという、、、
昔作成してた時は成功してたのになーと思って調べると、どうやら昔は成功してたみたい。watchOS6以降は... |
2021-05-06 14:04:37 | LINEのアニメーションスタンプ制作の落とし穴、、、失敗談
ゴールデンウィークにLINEスタンプを作成してみました。
作り切って申請も通したんですが、意図したアニメーションと違う、、、、
LINEクリエーターの画面だと、アニメーションのプレビュー... |
2021-05-01 18:05:35 | 久しぶりのAdmobをobjective-cに実装。コンパイルエラーだらけ。バーミッション不具合でエミュレータにインスコできない。
忘れないようにメモ
エミュレータにアプリをインストールする際にパーミッション系のエラーがでた時、また、iphone実機にインストールする際にも権限系のエラーが出る場合。
ターゲット→ex... |
Tweet | |||
|