Home > Software design >  SwiftUI: Animated rotation in different sides
SwiftUI: Animated rotation in different sides

Time:09-16

At first look question can seen ordinary but after spend few hour try out different techniques I still failed to achieve expected behavior... I want to control the rotation side of View depending in @State. If view in default position (chevron up) it should rotate down from the right side. If chevron is down it should rotate up from the left side.

And one more thing I discovered: in my work project I use Image instead SF Symbol with the same modification like in code example and by default it always rotates from the right side, but using SF Symbol it's going from left. I will be grateful if you explain why

struct Arrow: View {
    @State var showView = false
    var body: some View {
        VStack {
            Image(systemName: "chevron.up.circle")
                .resizable()
                .frame(width: 50, height: 50)
                .rotationEffect(.degrees(showView ? 180 : 360))
                .animation(Animation.easeInOut(duration: 0.3), value: showView)
        }
        .onTapGesture { showView.toggle() }
    }
}

CodePudding user response:

To always rotate in the same direction, maintain a rotationAngle that always increases (or always decreases) while animating:

struct ContentView: View {
    @State private var showView = false
    @State private var rotationAngle: Double = 0
    
    var body: some View {
        VStack {
            Image(systemName: "chevron.up.circle")
                .resizable()
                .frame(width: 50, height: 50)
                .rotationEffect(Angle(degrees: rotationAngle))
            
        }
        .onTapGesture {
            showView.toggle()
            withAnimation(.easeInOut(duration: 0.3)) {
                rotationAngle  = 180
            }
            rotationAngle = showView ? 180 : 0
        }
    }
}

Note: Use rotationAngle -= 180 to rotate in the other direction.


Showing rotation of chevron in simulator

  • Related