I am developing an audio visualizer MacOS app, and I want to use Quartz/CoreGraphics to render the time-varying spectrum coordinated with the playing audio. My Renderer code is:
import Cocoa
class Renderer: NSView {
override func draw(_ dirtyRect: NSRect) {
super.draw(dirtyRect)
NSColor.white.setFill()
bounds.fill()
guard let context = NSGraphicsContext.current?.cgContext else {return}
var x : CGFloat = 0.0
var y : CGFloat = 0.0
context.beginPath()
context.move(to: CGPoint(x: x, y: y))
for bin in 0 ..< 300 {
x = CGFloat(bin)
y = CGFloat(Global.spectrum[bin])
context.addLine(to: CGPoint(x: x, y: y))
}
context.setStrokeColor(CGColor( red: 1, green: 0, blue: 0, alpha: 1))
context.setLineWidth(1.0)
context.strokePath()
self.setNeedsDisplay(dirtyRect)
}
}
This draws the path once - using the initial all-zeroes values of the spectrum[] array - and then continues to draw that same all-zeroes line indefinitely. It does not update using the new values in the spectrum[] array. I used a print() statement to verify that the values themselves are being updated, but the draw function does not redraw the path using the updated spectrum values. What am I doing wrong?
The following demo shows how to update an NSView with random numbers created by a timer in a separate class to hopefully mimic your project. It may be run in Xcode by setting up a Swift project for MacOS, copy/pasting the source code into a new file called 'main.swift', and deleting the AppDelegate supplied by Apple. A draw function similar to what you posted is used.