Skip to content

Instantly share code, notes, and snippets.

@notcome
Created June 10, 2025 07:43
Show Gist options
  • Save notcome/3dd7428cd318fafd7731c05b2eaddd0a to your computer and use it in GitHub Desktop.
Save notcome/3dd7428cd318fafd7731c05b2eaddd0a to your computer and use it in GitHub Desktop.
SwiftUI gains ProMotion
import UIKit
import SwiftUI
import QuartzCore
var lastMediaTime: CFTimeInterval? = nil
struct YOffsetEffect: GeometryEffect {
var y: CGFloat
var animatableData: CGFloat {
get { y }
set { y = newValue }
}
func effectValue(size: CGSize) -> ProjectionTransform {
let current = CACurrentMediaTime()
if let last = lastMediaTime {
let ms = (current - last) * 1000
print(String(format: "%.1fms has elapsed since last update", ms))
} else {
print("First frame at mediaTime: \(current)")
}
lastMediaTime = current
return ProjectionTransform(CGAffineTransform(translationX: 0, y: y))
}
}
struct DualSquaresView: View {
@State private var toggled = false
var body: some View {
HStack(spacing: 40) {
Rectangle()
.fill(Color.blue)
.frame(width: 200, height: 200)
.offset(y: toggled ? 300 : -300)
.animation(.easeInOut(duration: 0.35), value: toggled)
.onTapGesture { toggled.toggle() }
Rectangle()
.fill(Color.orange)
.frame(width: 200, height: 200)
.modifier(YOffsetEffect(y: toggled ? 300 : -300))
.animation(.easeInOut(duration: 0.35), value: toggled)
.onTapGesture { toggled.toggle() }
}
.frame(maxWidth: .infinity, maxHeight: .infinity)
.background(Color(.systemBackground))
}
}
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
let hostingController = UIHostingController(rootView: DualSquaresView())
hostingController.view.translatesAutoresizingMaskIntoConstraints = false
addChild(hostingController)
view.addSubview(hostingController.view)
NSLayoutConstraint.activate([
hostingController.view.leadingAnchor.constraint(equalTo: view.leadingAnchor),
hostingController.view.trailingAnchor.constraint(equalTo: view.trailingAnchor),
hostingController.view.topAnchor.constraint(equalTo: view.topAnchor),
hostingController.view.bottomAnchor.constraint(equalTo: view.bottomAnchor)
])
hostingController.didMove(toParent: self)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment