'Canvas doesn't get redrawn in SwiftUI
I have a project in SwiftUI on macOS where I draw to a canvas twice per second.
This is my ContentView:
struct ContentView: view {
@State var score: Int = 0
var body: some View {
VStack {
Text("Score: \(self.score)")
.fixedSize(horizontal: true, vertical: true)
Canvas(renderer: { gc, size in
start(
gc: &gc,
size: size
onPoint: { newScore in
self.score = newScore
}
)
)
}
}
}
The start function:
var renderer: Renderer
func start(
gc: inout GraphicsContext,
size: size,
onPoint: @escaping (Int) -> ()
) {
if renderer != nil {
renderer!.set(gc: &gc)
} else {
renderer = Renderer(
context: &gc,
canvasSize: size,
onPoint: onPoint
)
startGameLoop(renderer: renderer!)
}
renderer!.drawFrame()
}
var timer: Timer
func startGameLoop(renderer: Renderer) {
timer = Timer.scheduledTimer(withTimeInterval: 0.5, repeats: true, block: {
renderer!.handleNextFrame()
}
}
And the renderer roughly looks like this:
class Renderer {
var gc: GraphicsContext
var size: CGSize
var cellSize: CGFloat
let pointCallback: (Int) -> ()
var player: (Int, Int) = (0,0)
init(
context: inout GraphicsContext,
canvasSize: CGSize,
onPoint: (Int) -> ()
) {
self.gc = gc
self.size = canvasSize
self.pointCallback = onPoint
self.cellSize = min(self.size.width, self.size.height)
}
}
extension Renderer {
func handleNextFrame() {
self.player = (self.player.0 + 1, self.player.1 + 1)
self.drawFrame
}
func drawFrame() {
self.gc.fill(
Path(
x: CGFloat(self.player.0) * self.cellSize,
y: CGFloat(self.player.1) * self.cellSize,
width: self.cellSize,
height: self.cellSize
)
)
}
}
So the handleNextFrame method is called twice per second, which calls the drawFrame method, drawing the position of the player to the canvas.
However, there is nothing being drawn to the canvas.
Only the first frame is drawn, which comes from the renderer!.drawFrame() in start. When a point is scored, the canvas is also redrawn, because the start function gets called again.
The problem is that there is nothing being drawn to the Canvas when the drawFrame is called from handleNextFrame.
Where lies my problem, and how can I fix this issue?
Thanks in advance,
Jonas
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|
