I am creating some animation and for smoothness on various devices I use CADisplayLink like this:
// DisplayLink.swift
import SwiftUI
class DisplayLink: NSObject, ObservableObject {
@Published var frameDuration: CFTimeInterval = 0
@Published var frameChange: Bool = false
static let sharedInstance: DisplayLink = DisplayLink()
func createDisplayLink() {
let displaylink = CADisplayLink(target: self, selector: #selector(frame))
displaylink.add(to: .current, forMode: RunLoop.Mode.default)
}
@objc func frame(displaylink: CADisplayLink) {
frameDuration = displaylink.targetTimestamp - displaylink.timestamp
frameChange.toggle()
}
}
Then I initialize it once in the application:
// App.swift
import SwiftUI
@main
struct App: App {
init() {
DisplayLink.sharedInstance.createDisplayLink()
}
var body: some Scene {
WindowGroup {
CircleView()
}
}
}
And I use it throughout the application as follows:
// CircleView.swift
import SwiftUI
struct CircleView: View {
@ObservedObject var displayLink = DisplayLink.sharedInstance
//
var body: some View {
//
.onChange(of: displayLink.frameChange) { _ in
print(displayLink.frameDuration)
}
}
Everything works great, but how correct is it to use this approach? Perhaps SwiftUI has ready-made methods for this?