0
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【SwiftUI】GeometryReaderで取得するサイズとUIScreen.main.boundsで取得するサイズの違い

Posted at

背景

SwiftUI実装している時に、画面サイズに応じて文字や画像サイズを変更したいと思い色々調べていたところGeometryReaderUIScreen.main.boundsという2つのサイズ取得方法が出てきたので備忘がてら残しておこうと思います。

GeometryReader

Viewの一種であり、VStackやHStack等と同様にView階層内に宣言をする必要がある。
GeometryProxyから以下の情報を取得することができる。
・自Viewのサイズ
・親Viewからの位置情報(x軸,y軸)

サンプル

これだけだとイメージがつかないと思うので、実際に画面イメージを見ていきたいと思います。
View構成
ContentViewに子Viewが8個ある。

ContentView(親View)
└ DetailCellView(子View)
  • 🔴 左上の赤丸部分
    子ViewのX,Y座標を表す基準地点。
    ここをx=0, y=0として子Viewの座標位置をGeometryProxyで取得する。
  • 🔵 青丸の部分
    DetailCellViewの一番右上のViewのX軸、Y軸の地点。
    この場合は基準地点からX軸方向に201、Y軸方向に62移動した地点が親Viewからの位置としてGeometryProxyで取得できる。
  • Width / Height
    DetailCellViewのサイズ。
    位置情報(X,Y軸)と異なり子Viewのサイズが同じであれば全て同じサイズとなる。
    image.png

ちなみに座標位置や子Viewのサイズは以下で取得可能です。

Text("X: \(Int(geometry.frame(in: .global).minX))")
Text("Y: \(Int(geometry.frame(in: .global).minY))")
Text("Width: \(Int(geometry.size.width))")
Text("Height: \(Int(geometry.size.height))")

UIScreen.main(非推奨)

端末全体の画面サイズ(ナビバー、タブバーを含めた物理的な画面サイズ)
つまり端末(iPhone 16, iPad 13 etc)によりサイズは固定となっている。

★UIScreen.mainは非推奨になった★

マルチウィンドウ対応を想定して非推奨になった。(と思われる。)

iOS13以降は複数ウィンドウを持つアプリもサポートするようになった。
それにより端末ごとの固定サイズを設定するとレイアウトが崩れてしまう可能性が出てくる。
例えば、
1. iPadでアプリを2画面表示(SplitView)
2. iPhoneでApp ClipやQuick Noteのような一時的ウィンドウ
3. macOS Catalystでウィンドウを複数開くアプリ

UIScreen.mainではデバイスのメイン画面を指しているため、

  • マルチウィンドウで表示している時
  • 外部ディスプレイに表示している時

でも常にアプリインストールしている端末のサイズ固定になってしまい、現在のウィンドウが表示されている値と無関係の値となるためレイアウトが崩れてしまう。

どうするか

.connectedScenesを使う

.connectedScenesとは、アプリが今接続しているsceneを返すプロパティです。
具体的には、動作している可能性があるsceneを位置に限らず返します。位置に限らずとは前画面にあるか背景にあるか画面外にあるかに限らずという意味です。
ただし、複数のUIWindowSceneが入っている可能性があるため、必ずしもfirstで欲しい値が取得できるとは限らないので注意が必要です。

let window = UIApplication.shared.connectedScenes.first as? UIWindowScene 
window.screen.bounds.width

まとめ

  • GeometryReader
    Viewに親子関係があり、親Viewからの位置や子View自身のサイズを取得したい場合に使用する。
  • UIScreen.main.bounds
    Apple非推奨となったため原則使用しない方が無難。
  • .connectedScenes
    画面サイズを取得したい場合は従来のUIScreen.main.boundsの代わりにこちらを利用する。

参考

0
2
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
0
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?