[英]Rendering bug? when using transparent NSWindow with SwiftUI for MacOS app
我正在使用 SwiftUI(來自 XCode 14.1 的最新版本)開發一個 macOS 應用程序,應用程序設置如下
import SwiftUI
@main
struct DemoApp: App {
@NSApplicationDelegateAdaptor(AppDelegate.self) private var appDelegate
var body: some Scene {
Window("demo", id: "demo") {
ContentView()
}.windowStyle(.hiddenTitleBar)
}
}
class AppDelegate: NSObject, NSApplicationDelegate, ObservableObject {
@Published var active: Bool = true
var mainWindow: NSWindow? {
for w in NSApplication.shared.windows {
if w.title == "demo" {
return w
}
}
return nil
}
private func setupMainWindow() {
}
@MainActor func applicationDidFinishLaunching(_: Notification) {
guard let w = mainWindow else {
print("nothing to setup")
return
}
w.level = .floating
w.backgroundColor = NSColor.clear
w.isOpaque = false
w.standardWindowButton(.zoomButton)?.isHidden = true
w.standardWindowButton(.closeButton)?.isHidden = true
w.standardWindowButton(.miniaturizeButton)?.isHidden = true
}
}
內容視圖定義如下
import SwiftUI
struct ContentView: View {
let timer = Timer.publish(every: 1, on: .main, in: .common).autoconnect()
@State var counter = 0
var body: some View {
VStack {
Image(systemName: "globe")
.imageScale(.large)
.foregroundColor(.accentColor)
Text("Hello, world! \(counter)").font(.system(size: 20).monospaced())
}
.padding().onReceive(timer) { _ in
counter += 1
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
基本上這個應用程序所做的是渲染一個透明的背景 window,上面有一些內容。 內容有一張 static 圖像和每秒更新一次的文本(帶有計數器)。
window 的初始渲染看起來不錯,但是一旦內容開始更新,就會渲染兩個重復的工件:一個來自第一個渲染結果,第二個來自最新的渲染結果。 第二個重疊在第一個之上。
這是在深色背景(另一個窗口)上渲染的 window 的屏幕截圖:
這是在白色背景(另一個窗口)上呈現的 window 的屏幕截圖:
在我看來,當 window 最初啟動時,因為它是透明的,不知何故操作系統或框架正在向渲染內容添加一些輪廓,正如您從“Hello world 0”字符串中看到的那樣,那里有一個輪廓。 也許框架正在嘗試做一些事情來將 window 內容與它下面的其他內容區分開來?
當 window 開始更新內容時,會重新繪制新內容,但最初捕獲的輪廓仍然存在,留下這個與當前渲染內容不匹配的奇怪工件。
我試圖禁用透明 window(具有純色背景或具有非零 alpha 的背景)。 這將完全消除問題。 添加的輪廓只有在 window 完全透明時才能看到。 據我所知,它與透明 window 背景和添加到內容中的輪廓有關。
我正在以稍微不同的方式配置 window,不需要AppDelegate
,但我看到了同樣的事情。 backgroundColor
為.clear
時,不僅渲染效果明顯,而且 window 也沒有邊框。
使用NSColor.white.withAlphaComponent(0.00001)
作為backgroundColor
消除了渲染問題,並且還正確顯示了邊框。
struct Mac_SwiftUI_testApp: App {
var body: some Scene {
Window("demo", id: "demo") {
ContentView()
.task {
NSApplication.shared.windows.forEach { window in
guard window.identifier?.rawValue == "demo" else { return }
window.standardWindowButton(.zoomButton)?.isHidden = true
window.standardWindowButton(.closeButton)?.isHidden = true
window.standardWindowButton(.miniaturizeButton)?.isHidden = true
window.backgroundColor = NSColor.white.withAlphaComponent(0.00001)
window.isOpaque = false
window.level = .floating
}
}
}
.windowStyle(.hiddenTitleBar)
}
}
backgroundColor =.clear
使用backgroundColor = NSColor.white.withAlphaComponent(0.00001)
在嘗試了一些事情之后,我發現設置
window.hasShadow = false
會解決你的問題。 它還刪除了清除 window 上的頂部“行”
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.