26
24

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

SwiftUIを触って分かったこと:①初期画面の設定方法

Posted at

下記ブログの転載です!
https://rc-code.info/ios/post-293/

SwiftUI をいじっていて、初回起動時の画面設定の仕方が今までと異なっていたので、ざっと紹介します。

SwiftUI を利用するか否かに限らず、アプリのUIを複数インスタンスで管理する方法(すなわち複数画面を単体アプリで管理する事と同意)を提供するために、Xcode11 から UIScene という概念が導入されましたので、そのことに少し触れようと思います。
詳細は こちら

今までの設定方法

今までは AppDelegatedidFinishLaunchingWithOptions 内で window を生成する、もしくは Deployment InfoMain Interface にて設定するのが一般的でした。

⬇️AppDelegate didFinishLaunchingWithOptions の例

class AppDelegate: UIResponder, UIApplicationDelegate {

    var window: UIWindow?

    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
        
        UNUserNotificationCenter.current().delegate = self
        
        window = UIWindow(frame: UIScreen.main.bounds)
        if let vc = UIStoryboard.init(name: "Main", bundle: nil).instantiateInitialViewController() {
            let navigationVc = UINavigationController(rootViewController: vc)
            self.window?.rootViewController = navigationVc
        }
	}
    以下省略
}

⬇️Main Interface への設定例
Main Interface 設定画面

新しい初期画面の設定方法

Xcode11 導入後は UIWindowSceneDelegate を利用した下記の方法が推奨されるようです。

1. UISceneConfiguration の設定

まず、AppDelegate に新しく追加された configurationForConnecting 関数にて、UISceneConfiguration として設定する対象を明記します。

class AppDelegate: UIResponder, UIApplicationDelegate {

    // MARK: UISceneSession Lifecycle

    func application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions) -> UISceneConfiguration {
        return UISceneConfiguration(name: "Default Configuration", sessionRole: connectingSceneSession.role)
    }
		他省略
}

上記で設定した Default ConfigurationInfo.plistApplication Scene Manifest に記載された Scene Configuration > Application Session Role > Item0 が当て込まれます。
下記が Info.plist の画像です。

Application Scene Manifest

この Item0 内で Configuration NameDefault Configuration に設定しているので、上記のコードを記載した時にこの Item0UISceneConfiguration として呼び出されるわけです。

Item0 には LaunchStoryboard Name という項目もあり、名前の通りここに記載した名前の Storyboard が 起動時の画面として呼び出されます。
また、Delegate Class Name に指定した名前のクラスが SceneDelegate (UIWindowSceneDelegate) として利用されます。

2. UIWindowSceneDelegate の設定

SceneDelegate では、今まで AppDelegatedidFinishLaunchingWithOptions 関数で指定していたように、window への割り当てができます。
そうです。
UIApplicationDelegate 同様、UIWindowSceneDelegatewindow のオプショナル定義を持っているのですw

class SceneDelegate: UIResponder, UIWindowSceneDelegate {

    var window: UIWindow?

    func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
        let window = UIWindow(frame: UIScreen.main.bounds)
        window.rootViewController = UIHostingController(rootView: ContentView())
        self.window = window
        window.makeKeyAndVisible()
    }
		以下省略
}

上記の ContentViewSwiftUIView プロトコルを満たした構造体です。
UIHostingController は描画のライフサイクルを担当する、いわば UIViewControllerController 部分だけを抽出し SwiftUI に合わせた感じのクラスのようです。(ざっくりとしか見てないので雑ですいませんw)

上記の例では、この UIHostingControllerwindowrootViewController として格納しています。

さて、これで ContentView がメインの View 構造体として設定されたので、あとはこの中身をゴリゴリと変えてく、ということになります。

ちなみに、ここまで説明してきた諸々の設定は、プロジェクト作成時に SwiftUI 項目にチェックを入れて開始するとデフォルトで入っています。
つまり、SwiftUI ではこの駆動方法が一般的ということになりそうですね!

今までのやり方はダメなの!?

冒頭に記載した今まで通りの初期画面設定ですが、Xcode11 でも UIApplicationDelegate プロトコルから var window のオプショナル定義は削除されておらず、引き続きこちらでも駆動はできるようです。
Main Interface の指定枠も同様です。

ですが、UIApplicationDelegate が端末とアプリケーションを繋ぐためのデリゲートを担当し、アプリの複数画面描画(とりわけ windowScene)を SceneDelegate が担うという構造になっていきそうな予感はプンプンしますね。
そのうち AppDelegate から window 関連の制約が deprecated になる気がします。

思っちゃったこと

Xcode11 から WindowScene を管理するための機構が多く見られます。
個人的な見解ですが、これは「個人が発信する」という文化にアプリケーションをマッチさせるための布石のように思います。

今回(2019/6 現在)の WWDC での発表を見ると、iPad を利用したプログラミング開発を斡旋するような機能や、PC と連動させて iPad を活用するような試みが見られます。
これは比較的大きな端末サイズに民衆を慣れさせることに成功した Apple が、次はその端末でもう少し上位の体験を簡単に実行できるようにするフェーズに入ったことの証明の様に感じます。
iPadOS だけではなく iOS でも同様の動きを取っていくでしょう。

現状、私たちは動画をアップする際、まずカメラで撮影し、編集し、それをSNSにアップロードします。コメントが来ればコメント欄を開き、いいねを押されればその人の画面に遷移してお返しをします。

これをシームレスに単体の端末内で実行できるとすれば、多くの民衆、もしくはプロのカメラマンや動画プロデューサーでさえ、その端末を利用するでしょう。

画面内に「カメラ自体のキャプチャ、編集枠、配信中の画像(編集を加えたキャプチャ)、コメント欄、Info枠...etc」などが混在し、それを直感的に掌の中で実行できる様になることを目指しているのではないでしょうか?
そのための布石としての UIWindowSceneDelegate である気がします。

そのうち、リジェクトの内容で
「ここのコメント画面は動画を見ながら確認できる様に別シーンで管理してくれたまえよ」
といった内容も出てくるのではなかろうかと。

26
24
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
26
24

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?