Reputation: 93
I'm branching off of the Apple ScreenCaptureKit sample project and I noticed the NSViewRepresentable
preview sometimes has a fade in animation applied when the NSView
is redrawn. I would like to remove this fade in. I believe this is SwiftUI automatically applying an animation — please correct me if I am wrong.
I've attached a video example of this below:
https://github.com/jasonhan-vassar/switcher/assets/34594853/e9f6ad8e-4d3e-4e00-b7fa-b37b396fe3cf
Here are some relevant parts of the code:
// CapturePreview.swift
import SwiftUI
struct CapturePreview: NSViewRepresentable {
// A layer that renders the video contents.
private let contentLayer = CALayer()
init() {
contentLayer.contentsGravity = .resizeAspect
}
func makeNSView(context: Context) -> CaptureVideoPreview {
CaptureVideoPreview(layer: contentLayer)
}
// The view isn't updatable. Updates to the layer's content are done in outputFrame(frame:).
func updateNSView(_ nsView: CaptureVideoPreview, context: Context) {}
// Called by ScreenRecorder as it receives new video frames.
func updateFrame(_ frame: CapturedFrame) {
contentLayer.contents = frame.surface
}
class CaptureVideoPreview: NSView {
// Create the preview with the video layer as the backing layer.
init(layer: CALayer) {
super.init(frame: .zero)
// Make this a layer-hosting view. First set the layer, then set wantsLayer to true.
self.layer = layer
wantsLayer = true
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
}
// ContentView.swift
import ScreenCaptureKit
import SwiftUI
struct ContentView: View {
@State var isUnauthorized = false
@StateObject var screenRecorder = ScreenRecorder()
var body: some View {
screenRecorder.capturePreview
.frame(maxWidth: .infinity, maxHeight: .infinity)
.aspectRatio(screenRecorder.contentSize, contentMode: .fit)
.overlay {
if isUnauthorized {
VStack {
Spacer()
Text("No screen recording permission.")
.font(.largeTitle)
.frame(maxWidth: .infinity)
.background(.red)
}
}
}
.onAppear {
Task {
if await screenRecorder.canRecord {
await screenRecorder.start()
} else {
isUnauthorized = true
}
}
}
}
}
So far, I've tried .animation(nil)
and various transaction stuff.
I'm new to Swift and SwiftUI, so apologies if this is trivial.
Upvotes: 1
Views: 116