UIImageView content resizes on update

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

Answered by helium97 in 751329022

Ok, I'm not sure if it's the best solution, but I found a possible fix by calling my function in view DidLayoutSubviews() as follows:

override func viewDidLayoutSubviews() {
        super.viewDidLayoutSubviews()
        updateWaveform()
    }
Accepted Answer

Ok, I'm not sure if it's the best solution, but I found a possible fix by calling my function in view DidLayoutSubviews() as follows:

override func viewDidLayoutSubviews() {
        super.viewDidLayoutSubviews()
        updateWaveform()
    }
UIImageView content resizes on update
 
 
Q