[SwiftUI][macOS] defaultPosition/defaultSize/windowResizability の使い方

SwiftUI2021

     
macOS 13 Ventura での SwiftUI の Window の大きさの扱われ方を調べてみました。

環境&対象

以下の環境で動作確認を行なっています。

  • macOS Ventura 13.1 Beta
  • Xcode 14.1
  • iOS 16.0

macOS アプリの Window

iOS アプリを開発していると考える必要はありませんが、macOS アプリでは、Window を使って表示されるという点を考慮することが必要です。

例えば、以下のような表示になった時に、「どちらの表示でも良い」というケースは少ないでしょう。(赤い border が アプリの表示領域を意味しています)
左側はぴったりおさまる Window size で、右側は、大きめ(?)な Window size です

ぴったり
おおきすぎ

macOS では、このように、View のサイズと View が表示される Window のサイズとの関係も考慮しなくてはいけません。

MEMO

macOS 12 Monterey までは、それなりに自動調整してくれていたのですが、macOS 13 Ventura になって、調整ロジックが変更されたようです。自分で開発しているアプリでの修正対応は、非常に大変でした。macOS 13 Ventura では Window サイズ周りの新しい API が追加されているようなので、どれくらい(?) 便利になったのかを確認したくなったのが、この記事を書いた動機です。

Ventura で追加された Window 関連 API

macOS 13 Ventura で追加された以下の Window 周りの View Modifier を確認していきます。
– defaultPosition
– defaultSize
– windowResizability

defaultPosition

defaultPosition を使うと、Window の配置位置のデフォルトを指定できます。

Apple のドキュメントは、こちら

func defaultPosition(_ position: UnitPoint) -> some Scene

引数の UnitPoint を使って、画面上の どの辺りの位置に 表示するかを指定します。

例えば、UnitPoint.top を指定して表示すると、画面中央の上辺に接するように配置されます。

MEMO

macOS では、アプリではなく macOS 自身が、前回のアプリの Window の位置や大きさを記憶していることがあります。(アプリの設定次第です)
defaultPosition は、macOS 側で記憶していない時にのみ有効です。

ターミナル上で以下のコマンドを使うことで、記憶されている情報を削除することができますので、必要に応じて以下のコマンドを使いながらの動作確認が必要です。(bundle-id は、アプリの bundle id に置き換えてください。)

defaults delete bundle-id

上記のコマンドは、アプリに関連するすべての情報を削除していますが、もう少し細かく引数指定すると、一部のみ削除することも可能です。

コマンドの詳細は、defaults –help で表示されます。

defaultSize

defaultSize を使うと デフォルトの Window size を指定できます。
Apple のドキュメントは、こちら

引数の異なる 2つの API が用意されています。

func defaultSize(_ size: CGSize) -> some Scene
func defaultSize(
    width: CGFloat,
    height: CGFloat
) -> some Scene

いずれも指定項目自体は同じです。
defaultPosition と同様に、前回アプリ起動時の情報が保存されている時には、保存されている情報が優先されます。

windowResizability

アプリの Window サイズを変更できるかどうかを制御することができます。
Apple のドキュメントは、こちら

func windowResizability(_ resizability: WindowResizability) -> some Scene

引数に、3種類指定することが可能です。

– contentSize
– contentMinSize
– automatic

デフォルトでは、automatic です。

contentSize

contentSize を指定すると、以下のような動作になります。
– content より小さくできない
– content より大きくできない

つまり、resize できないということです。

contentMinSize

contentMinSize を指定すると、以下のような動作になります。
– content より小さくできない
– content より大きくできる(制限なし)

automatic

automatic を指定すると、以下のような動作になります。
– WindowGroup や、DocumentGroup の Window に対しては、contentMinSizeと同じ
– Settings に対しては、contentSize と同じ

content のサイズ変更への追従

アプリによっては、状態によって表示内容が変わり、表示サイズまで変わることもあります。

そのような時にどのような処理がされるかも確認しました。

以下のように、ボタンを押すと content の大きさが変わるアプリを作って、確認しています。

import SwiftUI

@main
struct WindowSizeApp: App {
    var body: some Scene {
        WindowGroup {
            ContentView()
                .border(.red)
        }
        // windowResizability を切り替える
        .windowResizability(.contentMinSize)
//        .windowResizability(.contentSize)
    }
}
struct ContentView: View {
    @State private var size: CGFloat = 200
    var body: some View {
        VStack {
            Text("Content")
                .frame(width: size, height: size)
                .background(Color.yellow)
            HStack {
                Button(action: {
                    size += 200
                }, label: {Text("+200")})
                Button(action: {
                    size -= 100
                }, label: {Text("-100")})
            }
            .padding()
        }
    }
}

contentMinSize と contentSize について確認していきます。

contentMinSize

contentMinSize が指定されているケースで、content のサイズが変更されると、以下のような動作をしました。
– content が Window のサイズより大きくなると Window も大きくなる
– content が小さくなっても、Window を小さくすることはない

contentSize

contentSize が指定されているケースで、content のサイズが変更されると、以下のような動作をしました。
– content が大きくなると Window もあわせて大きくなる
– content が小さくなると Window を合わせて小さくなる

まとめ

Window 関連 View Modifier を調べてみました。

defaultPosition/defaultSize/windowResizable
  • defaultPosition/defaultSize は、Window の 位置とサイズを指定する
  • defaultPosition/defaultSize は事前に記憶されている値があると、効果はない
  • windowResizable は、Window のリサイズ可否を制御する
  • windowResizable は、content の大きさによっては Window の大きさを調整する

説明は以上です。
不明な点やおかしな点ありましたら、こちらまで。

SwiftUI おすすめ本

SwiftUI を理解するには、以下の本がおすすめです。

SwiftUI ViewMatery

SwiftUI で開発していくときに、ViewやLayoutのための適切なmodifierを探すのが大変です。
英語での説明になってしまいますが、以下の”SwiftUI Views Mastery Bundle”という本がビジュアル的に確認して探せるので、便利です。

英語ではありますが、1ページに コードと画面が並んでいるので、非常にわかりやすいです。

View に適用できる modifier もわかりやすく説明されているので、ビューの理解だけではなく、どのような装飾ができるかも簡単にわかります。

超便利です

SwiftUIViewsMastery

販売元のページは、こちらです。

SwiftUI 徹底入門

# SwiftUI は、毎年大きく改善されていますので、少し古くなってしまいましたが、いまでも 定番本です。

Swift学習におすすめの本

詳解Swift

Swift の学習には、詳解 Swift という書籍が、おすすめです。

著者は、Swift の初期から書籍を出していますし、Swift の前に主力言語だった Objective-C という言語についても同様の書籍を出しています。

最新版を購入するのがおすすめです。

現時点では、上記の Swift 5 に対応した第5版が最新版です。

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です