Trying to make a WaveFormView for the Guitar Tuner I am designing.
struct WaveFormView: View {
@State private var phase = 0.0
let amplitude: Double
let frequency: Double
let waveColor: Color
let echoes: Double
var body: some View {
ZStack {
ForEach(0..<5) { i in
Wave(amplitude: amplitude, frequency: frequency, phase: self.phase)
.stroke(waveColor.opacity((Double(i)/abs(echoes))), lineWidth: 2)
.offset(y: -CGFloat(i) * CGFloat(echoes))
}
.mask {
LinearGradient(gradient: Gradient(colors: [.clear, .white, . clear]), startPoint: .leading, endPoint: .trailing)
}
.onAppear {
withAnimation(Animation.linear(duration: 1).repeatForever(autoreverses: false)) {
self.phase = .pi * 2
}
}
}
}
}
When I put this inside a VStack, this will force the height of the VStack to be variable. It pulses with the same period of the phase animation in the WaveFormView.
Here's the ContentView:
struct TunerView: View {
@StateObject var controller = PitchData()
var pitchEngine = PitchEngine()
var body: some View {
VStack {
Spacer()
Text(controller.pitchString) // Note letter
.font(.system(size: 100))
Spacer()
ZStack{ // Here are the waves
WaveFormView(amplitude: 30,
frequency: controller.pitchFrequency,
waveColor: controller.isTuned ? .blue : .red,
echoes: controller.offsetCents)
WaveFormView(amplitude: 30,
frequency: controller.closestOffsetFrequency,
waveColor: controller.isTuned ? .blue : .red,
echoes: 1)
.frame(height: 400)
.border(.blue)
.onAppear { startPitchEngine() }
}
}
.border(.red)
}
BUT.... The most baffling thing is this: if I rotate the device landscape, then back portrait, the height of the VStack becomes stabilises to the value I want (full screen). No more bug.
Have posted a short video on my GitHub, please feel free to take a look. https://github.com/Salubrejoe/Tuner/blob/main/RPReplay_Final1685114259.MOV
Thanks in advance for any help!
I thought it might be the WFView itself, but the behaviour appears only after I embed it in a Stack.
If I do that and then use the spacer to push down the view, the graph gets indeed push down, but any other content overlayed on the original Stack keeps animating.
From the comments, by Yrb: