Home > Blockchain >  SwiftUI - How to animate button onto screen?
SwiftUI - How to animate button onto screen?

Time:02-26

I've got a button in SwiftUI that appears on a view depending on the count of an array, like this:

@State var arr ...

if arr.count > 0 {
  Button("click me!") {
    ...
  }
  .frame(maxHeight: .infinity, alignment: .bottom)
}

I want to animate the button to slide up from the bottom of the screen when the array count goes above 0, rather than it just abruptly appearing on the screen.

I tried the following lines: .transition(.slide) followed by .animation(.spring(), value: arr.count), but these seemingly had no effect. How can I accomplish this animation?

Thank you in advance.

CodePudding user response:

Using offset is an option

import SwiftUI

struct SlidingButtonView: View {
    @State var array: [Int] = [0]
    var body: some View {
        GeometryReader{ geo in
            VStack{
                Button("toggle", action: {
                    withAnimation(.linear(duration: 1)){
                        //Add to array
                        array.append(array.count)
                    }
                })
                //Moving button
                Button("tap me", action: {
                    print("tapme")
                })
                //Cheeck for even in sample code you can change the array.count parenthesis to meet your needs.
                    .offset(x: 0, y: (array.count
                                      % 2 == 0) ? 0: geo.size.height )
            }.frame(width: geo.size.width, height: geo.size.height, alignment: .center)
        }
    }
}

struct SlidingButtonView_Previews: PreviewProvider {
    static var previews: some View {
        SlidingButtonView()
    }
}

CodePudding user response:

The modifier .transition() works, you can check it in the example below. Are you sure that you are changing your @State variable using withAnimation { }?

This example slides both buttons up:

struct Example: View {
    
    @State private var array = [0, 1, 2]
    let trigger = 2
    
    var body: some View {
        VStack {
            Button {
                withAnimation {
                    array.append(1)
                }
            } label: {
                Text("Counter \(String(array.count))")
            }
            .padding()
            
            if array.count > trigger {
                Button("Click me!") {
                    print("Do nothing")
                }
                .frame(maxHeight: .infinity, alignment: .bottom)
                .transition(.move(edge: .bottom))
                .padding()
            }
        }
    }

(edited to use array.count as an example, removed transition from first button)

  • Related