Home > database >  How can I make a trim rotate in SWIFTUI?
How can I make a trim rotate in SWIFTUI?

Time:10-31

I have a RoundedRectangle and I want to make the trim rotate forever and make a nice animation from it. I added you this image here, so you can see what kind of trim I am talking about

Tried to make a rotation effect and 3d rotation effect, but it didn't work

@State private var show = false

var body: some View {
    ZStack {
        RoundedRectangle(cornerRadius: 20, style: .continuous)
            .foregroundColor(.gray.opacity(0.1))
            .frame(width: 195, height: 50)
        
        
        RoundedRectangle(cornerRadius: 20, style: .continuous)
            .trim(from: 0.25, to: 0.5)
            .stroke(style: StrokeStyle(lineWidth: 3, lineCap: .round))
            .frame(width: show ? 50 : 200, height: show ? 200 : 50)
            .rotationEffect(Angle(degrees: show ? 90 : 0))
            .animation(.linear.delay(1).repeatForever(autoreverses: true),
                       value: show)
        
        RoundedRectangle(cornerRadius: 20, style: .continuous)
            .trim(from: 0.75, to: 1)
            .stroke(style: StrokeStyle(lineWidth: 3, lineCap: .round))
            .frame(width: show ? 50 : 200, height: show ? 200 : 50)
            .rotationEffect(Angle(degrees: show ? 90 : 0))
            .animation(.linear.delay(1).repeatForever(autoreverses: true),
                       value: show)
        
        Text("title")
            .foregroundStyle(LinearGradient(gradient: Gradient(colors: colors),
                                            startPoint: .topLeading,
                                            endPoint: .bottomTrailing))
    }
    .onAppear {
        show.toggle()
    }

THis is my code. Made it move, but not the desired way... could be smoother and like two snakes going one after the other one

CodePudding user response:

enter image description here


Animate the changing of the trim offsets. Since it is difficult to animate past the boundaries of 0 and 1, use .rotation(Angle(degrees: 180)) to always stay within the boundaries of 0 and 1:

struct ContentView: View {
    let colors = [Color.green, Color.blue]
    @State private var offset = 0.0
    
    var body: some View {
        ZStack {
            RoundedRectangle(cornerRadius: 20, style: .continuous)
                .foregroundColor(.gray.opacity(0.1))
                .frame(width: 195, height: 50)
            
            RoundedRectangle(cornerRadius: 20, style: .continuous)
                .trim(from: 0.25   offset, to: 0.5   offset)
                .stroke(style: StrokeStyle(lineWidth: 3, lineCap: .round))
                .frame(width: 195, height: 50)
 
            RoundedRectangle(cornerRadius: 20, style: .continuous)
                .trim(from: 0.25   offset, to: 0.5   offset)
                .stroke(style: StrokeStyle(lineWidth: 3, lineCap: .round))
                .rotation(Angle(degrees: 180))
                .frame(width: 195, height: 50)
            
            Text("title")
                .foregroundStyle(LinearGradient(gradient: Gradient(colors: colors),
                                                startPoint: .topLeading,
                                                endPoint: .bottomTrailing))
        }
        .onAppear {
            withAnimation(.linear(duration: 0.75).repeatForever(autoreverses: false)) {
                offset = 0.5
            }
        }
    }
}

Optimizing the code

Since the two "snakes" are identical except for the 180º rotation, we can code this with a ForEach:

ForEach([0.0, 180.0], id: \.self) { rotation in
    RoundedRectangle(cornerRadius: 20, style: .continuous)
        .trim(from: 0.25   offset, to: 0.5   offset)
        .stroke(style: StrokeStyle(lineWidth: 3, lineCap: .round))
        .rotation(Angle(degrees: rotation))
        .frame(width: 195, height: 50)
}

  • Related