Hi everyone, I'm pretty new to iOS development. As part of an application I'm creating, I allow users to create personalised haptic vibrations. They can change frequency and amplitude through sliders and see the waveform (its path is inside the UIImageView) updated in real time.
Everything works, but there's one bug that I'm really struggling to solve...
When I open the screen the waveform is not in the desired position (seems like it doesn't recognise the full width and height of the container), but as soon as I move one of the sliders, the image gets updated and goes to its right place...
All the constraints are set in the Storyboard.
I've tried to call the update of the waveform in the "viewDidLoad", but the issue remains... Here's part of my code relative to the problem:
import UIKit
import CoreHaptics
class CustomViewController: UIViewController {
@IBOutlet weak var waveformImageView: UIImageView!
@IBOutlet weak var timeTitle: UILabel!
@IBOutlet weak var timeLabel: UITextField!
@IBOutlet weak var timeSlider: UISlider!
@IBOutlet weak var frequencyTitle: UILabel!
@IBOutlet weak var frequencyLabel: UITextField!
@IBOutlet weak var frequencySlider: UISlider!
@IBOutlet weak var amplitudeTitle: UILabel!
@IBOutlet weak var amplitudeLabel: UITextField!
@IBOutlet weak var amplitudeSlider: UISlider!
override func viewDidLoad() {
super.viewDidLoad()
updateWaveform()
}
/* THIS IS THE FUNCTION THAT CREATES AND DRAWS THE WAVEFORM */
func updateWaveform() {
let frequency = frequencySlider.value * 10 + 1
let amplitude = amplitudeSlider.value
let duration = timeSlider.value
/* Calculate the number of data points to generate based on the duration */
let sampleRate: Double = 44100
let numSamples = Int(1 * sampleRate)
/* Generate the waveform data */
let omega = 2 * Double.pi * Double(frequency)
let timeValues = (0..<numSamples).map { Double($0) / sampleRate }
let sinValues = timeValues.map { sin(omega * $0) }
let waveform = sinValues.map { $0 * Double(amplitude) }
/* Create a path for the waveform */
let waveformPath = UIBezierPath()
waveformPath.move(to: CGPoint(x: 0, y: waveformImageView.bounds.height / 2))
for i in 0..<numSamples {
let x = CGFloat(i) / CGFloat(numSamples) * waveformImageView.bounds.width
let y = (waveformImageView.bounds.height - 4) / 2 - CGFloat(waveform[i]) / 2 * (waveformImageView.bounds.height - 4)
waveformPath.addLine(to: CGPoint(x: x, y: y + 2))
}
/* Create a shape layer for the waveform */
let waveformLayer = CAShapeLayer()
waveformLayer.path = waveformPath.cgPath
waveformLayer.strokeColor = UIColor.systemBlue.cgColor
waveformLayer.lineWidth = 4
waveformLayer.fillColor = nil
/* Remove any previous waveform layers from the image view */
waveformImageView.layer.sublayers?.forEach { $0.removeFromSuperlayer() }
/* Add the waveform layer to the image view */
waveformImageView.layer.addSublayer(waveformLayer)
}```