BenJacob
BenJacob

Reputation: 987

Animating a View by its height in SwiftUI

I am attempting to make a view which will animate another content view in from the bottom of the screen. The below code works, however, as the content view will have unknown height the 200 offset may not be correct. How can I get the height of the content in order to offset the view correctly?

struct Test<Content>: View where Content : View {
    @State var showing: Bool = false
    var content: Content

    var body: some View {
        VStack {
            Button(action: {
                withAnimation {
                    self.showing.toggle()
                }
            }) {
                Text("Toggle")
            }

            Spacer()

            HStack {
                Spacer()

                content

                Spacer()
            }
            .background(Color.red)
            .padding(10)
            .offset(y: showing ? 200 : 0)

        }
    }
}

Upvotes: 3

Views: 1867

Answers (1)

Asperi
Asperi

Reputation: 257583

Here is possible approach to read content height directly from it during alignment...

struct Test<Content>: View where Content : View {
    var content: Content

    @State private var showing: Bool = false
    @State private var contentHeight: CGFloat = .zero

    var body: some View {
        VStack {
            Button(action: {
                withAnimation {
                    self.showing.toggle()
                }
            }) {
                Text("Toggle")
            }

            Spacer()

            HStack {
                Spacer()

                content
                    .alignmentGuide(VerticalAlignment.center) { d in
                        DispatchQueue.main.async {
                            self.contentHeight = d.height
                        }
                        return d[VerticalAlignment.center]
                    }

                Spacer()
            }
            .background(Color.red)
            .padding(10)
            .offset(y: showing ? contentHeight : 0)

        }
    }
}

Upvotes: 4

Related Questions