Skip to content

Instantly share code, notes, and snippets.

@timothycosta
Last active April 3, 2020 00:43
Show Gist options
  • Save timothycosta/6c213e930f34b8c91d3551f35438c38c to your computer and use it in GitHub Desktop.
Save timothycosta/6c213e930f34b8c91d3551f35438c38c to your computer and use it in GitHub Desktop.
A CADisplayLink in a BindableObject
//
// CADisplayLinkBinding.swift
// lingq-5
//
// Created by Timothy Costa on 2019/07/11.
// Copyright © 2019 timothycosta.com. All rights reserved.
//
import Combine
import SwiftUI
class CADisplayLinkBinding: NSObject, BindableObject {
let didChange = PassthroughSubject<CADisplayLinkBinding, Never>()
private(set) var progress: Double = 0.0
private(set) var startTime: CFTimeInterval = 0.0
private(set) var duration: CFTimeInterval = 0.0
private(set) lazy var displayLink: CADisplayLink = {
let link = CADisplayLink(target: self, selector: #selector(tick))
link.add(to: .main, forMode: .common)
link.isPaused = true
return link
}()
func run(for duration: CFTimeInterval) {
let now = CACurrentMediaTime()
self.progress = 0.0
self.startTime = now
self.duration = duration
self.displayLink.isPaused = false
}
@objc private func tick() {
let elapsed = CACurrentMediaTime() - self.startTime
self.progress = min(1.0, elapsed / self.duration)
self.displayLink.isPaused = self.progress >= 1.0
self.didChange.send(self)
}
deinit {
self.displayLink.invalidate()
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment