はじめに
SwiftUIフレームワークに内包されている構造体の内、頻繁に利用する構造体を備忘録的にまとめようと思います。
- Views
- Controls
- Layout ☆本記事ではここが対象
- Paints
- Other
- Modifiers
- Controls
- Effects
- Layout
- Text
- Image
- List
- Styles
- Accessibility
- Events
- Gestures
- Shape Modifiers
- Other
など
今後残りの部分についてもまとめていければと思っています。
また、端末で動作確認できるようにもしているので、もし興味があればローカルで端末にビルドいただければと思います。
ソースコード
Views
Layout
Depth Stack


Group {
Text("ZStack")
ZStack {
ForEach(0..<colors.count) {
Rectangle()
.fill(colors[$0])
.frame(width: 100, height: 100)
.offset(x: CGFloat($0) * 10.0,
y: CGFloat($0) * 10.0)
}
}.padding(.bottom, 70)
}
Group {
Text("ZStack(alignment: .center)")
ZStack(alignment: .center) {
Rectangle()
.fill(Color.red)
.frame(width: 100, height: 50)
Rectangle()
.fill(Color.blue)
.frame(width:50, height: 100)
}
.border(Color.green, width: 1)
}
Group {
Text("ZStack(alignment: .bottomLeading)")
ZStack(alignment: .bottomLeading) {
Rectangle()
.fill(Color.red)
.frame(width: 100, height: 50)
Rectangle()
.fill(Color.blue)
.frame(width:50, height: 100)
}
.border(Color.green, width: 1)
}
Group {
Text("ZStack(alignment: .bottomTrailing)")
ZStack(alignment: .bottomTrailing) {
Rectangle()
.fill(Color.red)
.frame(width: 100, height: 50)
Rectangle()
.fill(Color.blue)
.frame(width:50, height: 100)
}
.border(Color.green, width: 1)
}
Group {
Text("ZStack(alignment: .topLeading)")
ZStack(alignment: .topLeading) {
Rectangle()
.fill(Color.red)
.frame(width: 100, height: 50)
Rectangle()
.fill(Color.blue)
.frame(width:50, height: 100)
}
.border(Color.green, width: 1)
}
Group {
Text("ZStack(alignment: .topTrailing)")
ZStack(alignment: .topTrailing) {
Rectangle()
.fill(Color.red)
.frame(width: 100, height: 50)
Rectangle()
.fill(Color.blue)
.frame(width:50, height: 100)
}
.border(Color.green, width: 1)
}
Group {
Text("ZStack(alignment: .top)")
ZStack(alignment: .top) {
Rectangle()
.fill(Color.red)
.frame(width: 100, height: 50)
Rectangle()
.fill(Color.blue)
.frame(width:50, height: 100)
}
.border(Color.green, width: 1)
}
Group {
Text("ZStack(alignment: .leading)")
ZStack(alignment: .leading) {
Rectangle()
.fill(Color.red)
.frame(width: 100, height: 50)
Rectangle()
.fill(Color.blue)
.frame(width:50, height: 100)
}
.border(Color.green, width: 1)
}
Group {
Text("ZStack(alignment: .trailing)")
ZStack(alignment: .trailing) {
Rectangle()
.fill(Color.red)
.frame(width: 100, height: 50)
Rectangle()
.fill(Color.blue)
.frame(width:50, height: 100)
}
.border(Color.green, width: 1)
}
HStack

var body: some View {
VStack {
Text("default")
.frame(maxWidth: 400, alignment: .leading)
.padding(.top, 20)
HStack {
Text("First")
.border(Color.red, width: 2.0)
Image(systemName: "2.circle")
.resizable()
.frame(width: 60, height: 60)
.border(Color.green, width: 2.0)
Text("Third Third Third Third Third")
.border(Color.blue, width: 2.0)
}
.frame(width: 400)
.border(Color.red)
Text("alignment: .top")
.frame(maxWidth: 400, alignment: .leading)
.padding(.top, 20)
HStack(alignment: .top) {
Text("First")
.border(Color.red, width: 2.0)
Image(systemName: "2.circle")
.resizable()
.frame(width: 60, height: 60)
.border(Color.green, width: 2.0)
Text("Third Third Third Third Third")
.border(Color.blue, width: 2.0)
}
.frame(width: 400)
.border(Color.red)
Text("alignment: .bottom")
.frame(maxWidth: 400, alignment: .leading)
.padding(.top, 20)
HStack(alignment: .bottom) {
Text("First")
.border(Color.red, width: 2.0)
Image(systemName: "2.circle")
.resizable()
.frame(width: 60, height: 60)
.border(Color.green, width: 2.0)
Text("Third Third Third Third Third")
.border(Color.blue, width: 2.0)
}
.frame(width: 400)
.border(Color.red)
Text("spacing: 50")
.frame(maxWidth: 400, alignment: .leading)
.padding(.top, 20)
HStack(spacing: 50) {
Text("First")
.border(Color.red, width: 2.0)
Image(systemName: "2.circle")
.resizable()
.frame(width: 60, height: 60)
.border(Color.green, width: 2.0)
Text("Third Third Third Third Third")
.border(Color.blue, width: 2.0)
}
.frame(width: 400)
.border(Color.red)
}
}
GeometryReader

var body: some View {
ScrollView(.vertical) {
VStack {
GeometryReader { geometry in
Text(#"""
geometry.frame(in: .global).origin.x: \#(geometry.frame(in: .global).origin.x)
geometry.frame(in: .global).origin.y: \#(geometry.frame(in: .global).origin.y)
geometry.frame(in: .global).width: \#(geometry.frame(in: .global).width)
geometry.frame(in: .global).height: \#(geometry.frame(in: .global).height)
geometry.frame(in: .global).minX: \#(geometry.frame(in: .global).minX)
geometry.frame(in: .global).midX: \#(geometry.frame(in: .global).midX)
geometry.frame(in: .global).maxX: \#(geometry.frame(in: .global).maxX)
geometry.frame(in: .global).minY: \#(geometry.frame(in: .global).minY)
geometry.frame(in: .global).midY: \#(geometry.frame(in: .global).midY)
geometry.frame(in: .global).maxY: \#(geometry.frame(in: .global).maxY)
"""#)
}
.frame(height: 250)
.border(Color.red, width: 2.0)
GeometryReader { geometry in
Text(#"""
geometry.frame(in: .local).origin.x: \#(geometry.frame(in: .local).origin.x)
geometry.frame(in: .local).origin.y: \#(geometry.frame(in: .local).origin.y)
geometry.frame(in: .local).width: \#(geometry.frame(in: .local).width)
geometry.frame(in: .local).height: \#(geometry.frame(in: .local).height)
geometry.frame(in: .local).minX: \#(geometry.frame(in: .local).minX)
geometry.frame(in: .local).midX: \#(geometry.frame(in: .local).midX)
geometry.frame(in: .local).maxX: \#(geometry.frame(in: .local).maxX)
geometry.frame(in: .local).minY: \#(geometry.frame(in: .local).minY)
geometry.frame(in: .local).midY: \#(geometry.frame(in: .local).midY)
geometry.frame(in: .local).maxY: \#(geometry.frame(in: .local).maxY)
"""#)
}
.frame(height: 250)
.border(Color.green, width: 2.0)
GeometryReader { geometry in
Text(#"""
geometry.size.debugDescription: \#(geometry.size.debugDescription)
"""#)
}
.frame(height: 100)
.border(Color.green, width: 2.0)
}
}
}
LazyHGrid


var rows1: [GridItem] =
Array(repeating: .init(.fixed(40)), count: 2)
var rows2: [GridItem] =
Array(repeating: .init(.fixed(80)), count: 2)
var rows3: [GridItem] =
Array(repeating: .init(.fixed(40)), count: 4)
var rows4: [GridItem] =
Array(repeating: .init(.flexible(minimum: 40, maximum: 100)), count: 4)
var rows5: [GridItem] =
Array(repeating: .init(.adaptive(minimum: 40, maximum: 100)), count: 4)
var body: some View {
ScrollView(.vertical){
VStack {
Group {
Text("Array(repeating: .init(.fixed(40)), count: 2)")
ScrollView(.horizontal) {
LazyHGrid(rows: rows1, alignment: .top) {
ForEach((0...79), id: \.self) {
let codepoint = $0 + 0x1f600
let emoji = String(Character(UnicodeScalar(codepoint)!))
Text("\(emoji)")
.font(.largeTitle)
}
}
}.border(Color.red, width: 2)
}
Group {
Text("Array(repeating: .init(.fixed(80)), count: 2)")
ScrollView(.horizontal) {
LazyHGrid(rows: rows2, alignment: .top) {
ForEach((0...79), id: \.self) {
let codepoint = $0 + 0x1f600
let emoji = String(Character(UnicodeScalar(codepoint)!))
Text("\(emoji)")
.font(.largeTitle)
}
}
}.border(Color.red, width: 2)
}
Group {
Text("Array(repeating: .init(.fixed(40)), count: 4)")
ScrollView(.horizontal) {
LazyHGrid(rows: rows3, alignment: .top) {
ForEach((0...79), id: \.self) {
let codepoint = $0 + 0x1f600
let emoji = String(Character(UnicodeScalar(codepoint)!))
Text("\(emoji)")
.font(.largeTitle)
}
}
}.border(Color.red, width: 2)
}
Group {
Text("Array(repeating: .init(.flexible(minimum: 40, maximum: 100)), count: 4)")
ScrollView(.horizontal) {
LazyHGrid(rows: rows4, alignment: .top) {
ForEach((0...79), id: \.self) {
let codepoint = $0 + 0x1f600
let emoji = String(Character(UnicodeScalar(codepoint)!))
Text("\(emoji)")
.font(.largeTitle)
}
}
}.border(Color.red, width: 2)
}
Group {
Text("Array(repeating: .init(.adaptive(minimum: 40, maximum: 100)), count: 4)")
ScrollView(.horizontal) {
LazyHGrid(rows: rows5, alignment: .top) {
ForEach((0...79), id: \.self) {
let codepoint = $0 + 0x1f600
let emoji = String(Character(UnicodeScalar(codepoint)!))
Text("\(emoji)")
.font(.largeTitle)
}
}
}.border(Color.red, width: 2)
}
}
}
}
LazyHStack

@State private var showedIndex = ""
@State private var showedIndex2 = ""
var body: some View {
VStack {
Text("HStack")
ScrollView(.horizontal) {
HStack(alignment: .center, spacing: 10) {
Section(header: Text("header"), footer: Text("footer")) {
ForEach(1...20, id: \.self) { count in
Image(systemName: "\(count).square")
.font(.largeTitle)
.frame(height: 70)
.onAppear(perform: {
showedIndex += "\(count) "
})
}
}
}
}
Text("showedIndex: \(showedIndex)")
.padding(.bottom, 50)
Text("LazyHStack ")
ScrollView(.horizontal) {
LazyHStack(alignment: .center, spacing: 10) {
Section(header: Text("header"), footer: Text("footer")) {
ForEach(1...20, id: \.self) { count in
Image(systemName: "\(count).square")
.font(.largeTitle)
.frame(height: 70)
.onAppear(perform: {
showedIndex2 += "\(count) "
})
}
}
}.frame(height: 70)
}
Text("showedIndex: \(showedIndex2)")
.padding(.bottom, 50)
Text("LazyHStack pinnedViews: .sectionHeaders")
ScrollView(.horizontal) {
LazyHStack(alignment: .center, spacing: 10, pinnedViews: .sectionHeaders) {
Section(header: Text("header"), footer: Text("footer")) {
ForEach(1...20, id: \.self) { count in
Image(systemName: "\(count).square")
.font(.largeTitle)
.frame(height: 70)
}
}
}.frame(height: 70)
}
}
}
LazyVGrid



var columns: [GridItem] =
Array(repeating: .init(.flexible()), count: 2)
var columns2: [GridItem] =
Array(repeating: .init(.fixed(80)), count: 2)
var columns3: [GridItem] =
Array(repeating: .init(.flexible(minimum: 80, maximum: 100)), count: 2)
var columns4: [GridItem] =
Array(repeating: .init(.flexible(minimum: 80, maximum: 100)), count: 4)
var columns5: [GridItem] =
Array(repeating: .init(.adaptive(minimum: 80)), count: 2)
var body: some View {
ScrollView(.vertical) {
VStack {
Group {
Text("Array(repeating: .init(.flexible()), count: 2)")
ScrollView {
LazyVGrid(columns: columns) {
ForEach((0...79), id: \.self) {
let codepoint = $0 + 0x1f600
let codepointString = String(format: "%02X", codepoint)
Text("\(codepointString)")
let emoji = String(Character(UnicodeScalar(codepoint)!))
Text("\(emoji)")
}
}.font(.largeTitle)
}.frame(height: 200)
.border(Color.red, width: 2)
}
Group {
Text("Array(repeating: .init(.fixed(80)), count: 2)")
ScrollView {
LazyVGrid(columns: columns2) {
ForEach((0...79), id: \.self) {
let codepoint = $0 + 0x1f600
let codepointString = String(format: "%02X", codepoint)
Text("\(codepointString)")
let emoji = String(Character(UnicodeScalar(codepoint)!))
Text("\(emoji)")
}
}.font(.largeTitle)
}.frame(height: 200)
.border(Color.red, width: 2)
}
Group {
Text("Array(repeating: .init(.flexible(minimum: 80, maximum: 100)), count: 2)")
ScrollView {
LazyVGrid(columns: columns3) {
ForEach((0...79), id: \.self) {
let codepoint = $0 + 0x1f600
let codepointString = String(format: "%02X", codepoint)
Text("\(codepointString)")
let emoji = String(Character(UnicodeScalar(codepoint)!))
Text("\(emoji)")
}
}.font(.largeTitle)
}.frame(height: 200)
.border(Color.red, width: 2)
}
Group {
Text("Array(repeating: .init(.flexible(minimum: 80, maximum: 100)), count: 4)")
ScrollView {
LazyVGrid(columns: columns4) {
ForEach((0...79), id: \.self) {
let codepoint = $0 + 0x1f600
let codepointString = String(format: "%02X", codepoint)
Text("\(codepointString)")
let emoji = String(Character(UnicodeScalar(codepoint)!))
Text("\(emoji)")
}
}.font(.largeTitle)
}.frame(height: 200)
.border(Color.red, width: 2)
}
Group {
Text("Array(repeating: .init(.adaptive(minimum: 80)), count: 2)")
ScrollView {
LazyVGrid(columns: columns5) {
ForEach((0...79), id: \.self) {
let codepoint = $0 + 0x1f600
let codepointString = String(format: "%02X", codepoint)
Text("\(codepointString)")
let emoji = String(Character(UnicodeScalar(codepoint)!))
Text("\(emoji)")
}
}.font(.largeTitle)
}.frame(height: 200)
.border(Color.red, width: 2)
}
}
}
}
LazyVStack

@State private var showedIndex = ""
@State private var showedIndex2 = ""
var body: some View {
ScrollView(.vertical) {
VStack {
Text("VStack")
ScrollView(.vertical) {
VStack(alignment: .center, spacing: 10) {
Section(header: Text("header"), footer: Text("footer")) {
ForEach(1...20, id: \.self) { count in
Image(systemName: "\(count).square")
.font(.largeTitle)
.frame(height: 70)
.onAppear(perform: {
showedIndex += "\(count) "
})
}
}
}
}.frame(height: 200)
Text("showedIndex: \(showedIndex)")
.padding(.bottom, 50)
Text("LazyVStack ")
ScrollView(.vertical) {
LazyVStack(alignment: .center, spacing: 10) {
Section(header: Text("header"), footer: Text("footer")) {
ForEach(1...20, id: \.self) { count in
Image(systemName: "\(count).square")
.font(.largeTitle)
.frame(height: 70)
.onAppear(perform: {
showedIndex2 += "\(count) "
})
}
}
}
}.frame(height: 200)
Text("showedIndex: \(showedIndex2)")
.padding(.bottom, 50)
Text("LazyVStack pinnedViews: .sectionHeaders")
ScrollView(.vertical) {
LazyVStack(alignment: .center, spacing: 10, pinnedViews: .sectionHeaders) {
Section(header: Text("header"), footer: Text("footer")) {
ForEach(1...20, id: \.self) { count in
Image(systemName: "\(count).square")
.font(.largeTitle)
.frame(height: 70)
}
}
}
}.frame(height: 200)
}
}
}
ScrollViewReader

ScrollViewReader { proxy in
ScrollView {
Button("proxy.scrollTo(30, anchor: .top)") {
withAnimation {
proxy.scrollTo(30, anchor: .top)
}
}.id(0)
Button("proxy.scrollTo(30, anchor: .center)") {
withAnimation {
proxy.scrollTo(30, anchor: .center)
}
}.id(0)
Button("proxy.scrollTo(30, anchor: .bottom)") {
withAnimation {
proxy.scrollTo(30, anchor: .bottom)
}
}.id(0)
ForEach(1..<51) { index in
Image(systemName: "\(index).square")
.font(.largeTitle)
.frame(height: 70)
.id(index)
}
Button("Top") {
withAnimation {
proxy.scrollTo(0)
}
}
}
}
VStack

VStack {
Text("default")
.frame(maxWidth: 400, alignment: .leading)
.padding(.top, 20)
VStack {
Text("First")
.border(Color.red, width: 2.0)
Image(systemName: "2.circle")
.resizable()
.frame(width: 60, height: 60)
.border(Color.green, width: 2.0)
Text("Third Third Third Third Third")
.border(Color.blue, width: 2.0)
}
.frame(width: 400)
.border(Color.red)
Text("alignment: .leading")
.frame(maxWidth: 400, alignment: .leading)
.padding(.top, 20)
VStack(alignment: .leading) {
Text("First")
.border(Color.red, width: 2.0)
Image(systemName: "2.circle")
.resizable()
.frame(width: 60, height: 60)
.border(Color.green, width: 2.0)
Text("Third Third Third Third Third")
.border(Color.blue, width: 2.0)
}
.frame(width: 400)
.border(Color.red)
Text("alignment: .center")
.frame(maxWidth: 400, alignment: .leading)
.padding(.top, 20)
VStack(alignment: .center) {
Text("First")
.border(Color.red, width: 2.0)
Image(systemName: "2.circle")
.resizable()
.frame(width: 60, height: 60)
.border(Color.green, width: 2.0)
Text("Third Third Third Third Third")
.border(Color.blue, width: 2.0)
}
.frame(width: 400)
.border(Color.red)
Text("alignment: .trailing")
.frame(maxWidth: 400, alignment: .leading)
.padding(.top, 20)
VStack(alignment: .trailing) {
Text("First")
.border(Color.red, width: 2.0)
Image(systemName: "2.circle")
.resizable()
.frame(width: 60, height: 60)
.border(Color.green, width: 2.0)
Text("Third Third Third Third Third Third Third")
.border(Color.blue, width: 2.0)
}
.frame(width: 400)
.border(Color.red)
}
最後に
最後まで閲覧いただきありがとうございました。
今後時間を見つけて残りのStructについてもまとめていく予定です。