Sponsor Link
環境&対象
- 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 のサイズとの関係も考慮しなくてはいけません。
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 を指定して表示すると、画面中央の上辺に接するように配置されます。
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 は、Window の 位置とサイズを指定する
- defaultPosition/defaultSize は事前に記憶されている値があると、効果はない
- windowResizable は、Window のリサイズ可否を制御する
- windowResizable は、content の大きさによっては Window の大きさを調整する
説明は以上です。
不明な点やおかしな点ありましたら、こちらまで。
SwiftUI おすすめ本
SwiftUI を理解するには、以下の本がおすすめです。
SwiftUI ViewMatery
SwiftUI で開発していくときに、ViewやLayoutのための適切なmodifierを探すのが大変です。
英語での説明になってしまいますが、以下の”SwiftUI Views Mastery Bundle”という本がビジュアル的に確認して探せるので、便利です。
英語ではありますが、1ページに コードと画面が並んでいるので、非常にわかりやすいです。
View に適用できる modifier もわかりやすく説明されているので、ビューの理解だけではなく、どのような装飾ができるかも簡単にわかります。
超便利です
販売元のページは、こちらです。
SwiftUI 徹底入門
# SwiftUI は、毎年大きく改善されていますので、少し古くなってしまいましたが、いまでも 定番本です。
Swift学習におすすめの本
詳解Swift
Swift の学習には、詳解 Swift という書籍が、おすすめです。
著者は、Swift の初期から書籍を出していますし、Swift の前に主力言語だった Objective-C という言語についても同様の書籍を出しています。
最新版を購入するのがおすすめです。
現時点では、上記の Swift 5 に対応した第5版が最新版です。
Sponsor Link