ios – Form not re-animating in SwiftUI

0
15
ios – Form not re-animating in SwiftUI


To get your animation begin once more, you might want to reset section worth earlier than begin animation. After WaveView seem, section worth get set to .pi * 2, then while you press button, you simply set it to the identical worth, SwiftUI don’t see any change of section so your animation just isn’t run, additionally when onChange closure of isAnimating get known as, a brand new withAnimation block get known as due to this fact present animation repeatForever get cancel as a result of animation for section and power are stick collectively in AnimatablePair:

personal func animateWave() {
    section = 0 // <- reset section worth right here
    withAnimation(Animation.linear(period: 2).repeatForever(autoreverses: false)) {
        self.section = .pi * 2
    }
}

You possibly can remark out withAnimation block in onChange(of: isAnimating) to maintain repeatForever animation, however then you’ll not have animation when waveStrength change:

.onChange(of: isAnimating) { _, newValue in
    //withAnimation(.easeInOut(period: 0.5)) {
    waveStrength = newValue ? 50.0 : 0.0
    //}
    if newValue {
        animateWave()
    }
}

One other repair is to seperate section and waveStrength from AnimatablePair:

struct ShapheWave: View, @preconcurrency Animatable {
    var power: Double
    var frequency: Double
    var section: Double
    
    var animatableData: Double {
        get { section }
        set {
            self.section = newValue
        }
    }
    
    var physique: some View {
        Wave(power: power, frequency: frequency, section: section)
            .stroke(.black, lineWidth: 5)
    }
}
struct Wave: Form {
    var power: Double
    var frequency: Double
    var section: Double = .pi * 2
    var animatableData: Double {
        get { power }
        set {
            self.power = newValue
        }
    }
    
    func path(in rect: CGRect) -> Path {
        var path = Path()
        
        let width = Double(rect.width)
        let peak = Double(rect.peak)
        let midHeight = peak / 2
        let wavelength = width / frequency
        
        let firstX = 0.0
        let firstRelativeX = firstX / wavelength
        let firstSine = sin(firstRelativeX + section)
        let firstY = power * firstSine + midHeight
        path.transfer(to: CGPoint(x: firstX, y: firstY))
        
        for x in stride(from: 0.0, by: width, by: 1) {
            let relativeX = x / wavelength
            let sine = sin(relativeX + section)
            let y = power * sine + midHeight
            path.addLine(to: CGPoint(x: x, y: y))
        }
        
        return path
    }
}

struct WaveView: View {
    @Binding var isAnimating: Bool
    @State personal var section = 0.0
    @State personal var waveStrength = 50.0
    
    var physique: some View {
        VStack {
            ShapheWave(power: waveStrength, frequency: 30, section: section)
                .onChange(of: isAnimating) { _, newValue in
                    waveStrength = newValue ? 50.0 : 0.0
                }
                .onAppear {
                    animateWave()
                }
                .animation(.linear(period: 2).repeatForever(autoreverses: false), worth: section)              .animation(.easeInOut(period: 0.5), worth: waveStrength)
        }
    }
    
    personal func animateWave() {
        section = .pi * 2
    }
}

LEAVE A REPLY

Please enter your comment!
Please enter your name here