In SwiftUI how can I animate a button offset when displayed

If you would like to play with offset, this can get you started.

struct ContentView : View {
    @State private var offset: Length = 0

    var body: some View {
        Button(action: {}) { Text("Button") }
            .offset(x: 0.0, y: offset)
            .onAppear {
                withAnimation(.basic(duration: 5)) { self.offset = 100.0 }
            }
    }
}

I first suggested a .transition(.move(.top)), but I am updating my answer. Unless your button is on the border of the screen, it may not be a good fit. The move is limited to the size of the moved view. So you may need to use offset after all!

Note that to make it start way out of the screen, the initial value of offset can be negative.


First of all you need to create a transition. You could create an extension for AnyTransition or just create a variable. Use the move() modifier to tell the transition to move the view in from a specific edge

let transition = AnyTransition.move(edge: .top);

This alone only works if the view is at the edge of the screen. If your view is more towards the center you can use the combined() modifier to combine another transition such as offset() to add additional offset

let transition = AnyTransition
    .move(edge: .top)
    .combined(with:
        .offset(
            .init(width: 0, height: 100)
        )
    );

This transition will be for both showing and removing a view although you can use AnyTransition.asymmetric() to use different transitions for showing and removing a view

Next create a showButton bool (name this whatever) which will handle showing the button. This will use the @State property wrapper so SwiftUI will refresh the UI when changed.

@State var showButton: Bool = false;

Next you need to add the transition to your button and wrap your button within an if statement checking if the showButton bool is true

if (self.showButton == true) {
    Button(action: { }) {
        Text("Button")
    }
    .transition(transition);
}

Finally you can update the showButton bool to true or false within an animation block to animate the button transition. toggle() just reverses the state of the bool

withAnimation {
    self.showButton.toggle();
}

You can put your code in onAppear() and set the bool to true so the button is shown when the view appears. You can call onAppear() on most things like a VStack

.onAppear {
    withAnimation {
        self.showButton = true;
    }
}

Check the Apple docs to see what is available for AnyTransition https://developer.apple.com/documentation/swiftui/anytransition

Tags:

Swiftui