LoginSignup
3
4

More than 1 year has passed since last update.

SwiftUIに内包されているStructまとめ - ViewLayout編

Posted at

はじめに

SwiftUIフレームワークに内包されている構造体の内、頻繁に利用する構造体を備忘録的にまとめようと思います。

  • Views
    • Controls
    • Layout ☆本記事ではここが対象
    • Paints
    • Other
  • Modifiers
    • Controls
    • Effects
    • Layout
    • Text
    • Image
    • List
    • Styles
    • Accessibility
    • Events
    • Gestures
    • Shape Modifiers
    • Other

など
今後残りの部分についてもまとめていければと思っています。

また、端末で動作確認できるようにもしているので、もし興味があればローカルで端末にビルドいただければと思います。
ソースコード

Views

Layout

Depth Stack

ZStack
ZStack2

        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

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

LazyHGrid
LazyHGrid2

    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

LazyVGrid
LazyVGrid2
LazyVGrid3

    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

        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についてもまとめていく予定です。

3
4
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
3
4