はじめに
SwiftUIでそれぞれのViewのレイアウトをデザインする時に必要なGeometryReaderについて整理することを目的とする
開発環境
OSX 10.15.7 (Catalina)
Xcode 12.2.0
CocoaPods 1.10.0
SwiftUIのレイアウトシステム
Appをデザインするための基本的な考え方はHStack、VStack、ZStackを組み合わせです。複雑なレイアウトを実装していくためにそれぞれの特徴を理解する必要があります。
-
HStack
childViewを横一列に並べることができる。
"H": a horizontal line -
VStack
childViewを縦方向に並べることができる。
"V": a vertical line -
ZStack
childViewを重ねることができる。
"Z": overlap
参考文献
How to use stacks: HStack, VStack and ZStack in SwiftUI (Equivalent of UIStackView in UIKit)
import SwiftUI
struct ContentView: View {
var body: some View {
// a vertical line
VStack {
// a vertical line
VStack {
// overlap
ZStack {
// a horizontal line
HStack{
Image(systemName: "doc")
Text("First One")
}
}
// overlap
ZStack {
// a horizontal line
HStack{
Image(systemName: "doc")
Text("Two One")
}
}
}
}
}
}
GeometryReaderの考え方
参考文献
GeometryReaderはViewの一種であり、親のViewのサイズと自身の親のViewに対する位置を知るためのもの
実装の要点
struct ContentView: View {
var body: some View {
// a vertical line
// parent View
VStack {
// クロージャーの"g"は任意で設定可能
GeometryReader { g in
// a vertical line
VStack {
// overlap
ZStack {
// a horizontal line
HStack{
Image(systemName: "doc")
Text("First One")
}
// parentViewの幅いっぱい、縦は全体の1/2に設定。
}.frame(width: g.size.width, height: g.size.height/2, alignment: /*@START_MENU_TOKEN@*/.center/*@END_MENU_TOKEN@*/)
.background(Color.red)
// overlap
ZStack {
// a horizontal line
HStack{
Image(systemName: "doc")
Text("Two One")
}
// parentViewの幅いっぱい、縦は全体の1/2に設定。
}.frame(width: g.size.width, height: g.size.height/2, alignment: /*@START_MENU_TOKEN@*/.center/*@END_MENU_TOKEN@*/)
.background(Color.yellow)
}
}
}.frame(minWidth: 0, maxWidth: .infinity, minHeight: 0, maxHeight: .infinity)
}
}
現在、IPhoneは様々な画面サイズのデバイスが生産されています。それらのサイズに適したデザインをするためにはGeometryReaderでサイズを取得し、配置していく必要があります。
以下のイメージは画面サイズを1/3に設定したものです。height: g.size.height/3
の"3"は整数だけでなく、小数点で表記しても認識されます。これにより、さらに細かいレイアウトのデザインが可能です。
実装のイメージ
ログイン・サインアップViewのレイアウトイメージです。
全体の比率を計算して、レイアウトを決めていきます。