Regarding this tutorial...
It describes how to load frames from a video file and draw them one after another to a Metal view.
There is a while
loop that iterates over each frame and calls draw
on the view...
while sampleBuffer != nil {
...
displayView.draw()
...
}
Where should this loop go? I have tried it in viewDidLoad
and after a delay and lots of print outputs it only seems to show the final frame. It's as though you can't see updates to a view before viewDidLoad
has finished.
I suppose I would put it in viewWillAppear(_:)
or viewDidAppear(_:)
. However, this is the first time I've seen a draw command in a super tight loop like that, and it seems less than ideal.
If you would like to control the draw manually, I would recommend the use of a CADisplayLink
instead. The purpose of CADisplayLink
is it is timed to be in sync with the system update of the screen. You can also set a preferred frame rate, which is nice.
weak var displayLink: CADisplayLink?
func createDisplayLink() {
displayLink?.invalidate() // in case existing timer
let displayLink = CADisplayLink(target: self, selector: #selector(update(_:)))
displayLink.add(to: .main, forMode: .common)
displayLink.preferredFramesPerSecond = 30 // Optional set desired frame rate
self.displayLink = displayLink
}
@objc func update(_ displayLink: CADisplayLink) {
displayView.draw()
}
func viewWillAppear(_ animated: Bool) {
// You can create it earlier, but I prefer here
createDisplayLink()
}
func viewWillDisappear(_ animated: Bool) {
// Stop rending when view disappears
displayLink?.invalidate()
}