しめ鯖日記

swift, iPhoneアプリ開発, ruby on rails等のTipsや入門記事書いてます

【SwiftUI】GeometryReaderでViewのサイズを取得する

画面サイズによって処理を変えたかったため、GeometryReaderというクラスを使って画面サイズを取得しました。

Viewのサイズは下の形で取得できます。

struct ContentView: View {
    var body: some View {
        GeometryReader { geometry in
            Text(String("\(geometry.size)"))
        }
    }
}

実行すると下のようにViewのサイズが取得できます。

f:id:llcc:20201028105427p:plain

ただ上記ViewサイズはSafeAreaが除外されているので注意が必要です。
SafeAreaを取得したい場合はしたのように記述します。

struct ContentView: View {
    var body: some View {
        GeometryReader { geometry in
            Text(String("\(geometry.safeAreaInsets)"))
        }
    }
}

View全体ではなく、内側にあるViewのサイズを取りたい場合は下のように入れ子にします。

struct ContentView: View {
    var body: some View {
        VStack {
            Spacer().frame(height: 100)
            GeometryReader { geometry in
                Text(String("\(geometry.size)"))
            }
            Spacer().frame(height: 100)
        }
    }
}

実行すると内側のViewのサイズを取れました。

f:id:llcc:20201028110442p:plain

GeometryReaderはWidget上でも使う事ができます。

f:id:llcc:20201028110852p:plain

frameメソッドを使う事で、xとyも取得できます。
引数はCoordinateSpaceというクラスです。

struct ContentView: View {
    var body: some View {
        GeometryReader { geometry in
            Text(String("\(geometry.frame(in: .global))"))
        }
    }
}

実行結果は下のとおりです。
SafeAreaも含めた結果になるので注意が必要です。

f:id:llcc:20201028111312p:plain

CoordinateSpaceは自分でcoordinateSpaceメソッドを使って定義する事も可能です。
下の例ではVStackでTestという名前のCoordinateSpaceを定義して、それに対する位置を取得しています。

struct ContentView: View {
    var body: some View {
        VStack {
            Spacer().frame(height: 100)
            GeometryReader { geometry in
                Text(String("\(geometry.frame(in: .named("Test")))"))
            }
            Spacer().frame(height: 100)
        }.coordinateSpace(name: "Test")
    }
}

実行するとVStackに対する位置情報が取得できている事が分かります。

f:id:llcc:20201028111637p:plain