Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I make a trim rotate in SWIFTUI?

Tags:

swift

swiftui

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

like image 858
Rares Avatar asked Nov 18 '25 15:11

Rares


1 Answers

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)
}

like image 73
vacawama Avatar answered Nov 21 '25 08:11

vacawama



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!