弄清楚了!谢天谢地,没有任何黑客攻击
![在此处输入图像描述](https://i.stack.imgur.com/KsDVm.png)
规则
为了在没有问题中令人讨厌的伪影的情况下实现这种外观,您必须按照 macOS 想要的方式做一些事情。
1.不要设置你的NSWindow.backgroundColor = .clear
!
这首先是上面那些讨厌的文物的原因!保持窗口颜色不变将确保窗口在更改屏幕时正常工作。NSVisualEffectView
捕获窗口后面的图像并将其用作背景,因此无需使任何东西透明。
2.确保包含.titled
在窗口的styleMask中!
否则将呈现没有圆角的窗口。如果您尝试向 SwiftUI 视图添加圆角(就像我所做的那样),您仍然会有一个不透明的背景NSWindow
。如果您随后将窗口的背景颜色设置为.clear
(就像我再次所做的那样),就会出现阴影切割问题!但是,这并不意味着标题栏会妨碍您,它不会,我们稍后会谈到。
3. 将您添加NSVisualEffectView
到您的 SwiftUI 视图中!
我发现这比将视觉效果添加到NSWindow.contentView
子视图更容易。
解决方案
1. 所以从设置你的NSWindow
和 AppDelegate 开始吧!⤵︎
您所做的只是确保标题栏存在但隐藏。
import Cocoa
import SwiftUI
@main
class AppDelegate: NSObject, NSApplicationDelegate {
var window: NSWindow!
func applicationDidFinishLaunching(_ aNotification: Notification) {
// Create the SwiftUI view that provides the window contents.
let contentView = ContentView()
// Create the window and set the content view.
// Note: You can add any styleMasks you want, just don't remove the ones below.
window = NSWindow(
contentRect: NSRect(x: 0, y: 0, width: 300, height: 200),
styleMask: [.titled, .fullSizeContentView],
backing: .buffered, defer: false)
// Hide the titlebar
window.titlebarAppearsTransparent = true
window.titleVisibility = .hidden
// Hide all Titlebar Controls
window.standardWindowButton(.miniaturizeButton)?.isHidden = true
window.standardWindowButton(.closeButton)?.isHidden = true
window.standardWindowButton(.zoomButton)?.isHidden = true
// Set the contentView to the SwiftUI ContentView()
window.contentView = NSHostingView(rootView: contentView)
// Make sure the window is movable when grabbing it anywhere
window.isMovableByWindowBackground = true
// Saves frame position between opening / closing
window.setFrameAutosaveName("Main Window")
// Display the window
window.makeKeyAndOrderFront(nil)
window.center()
}
func applicationWillTerminate(_ aNotification: Notification) {
// Insert code here to tear down your application
}
}
此时您的窗口可能看起来像这样(如果从空白项目开始)。您可以看到“Hello world!” 由于标题栏,不完全居中。⤵︎
![在此处输入图像描述](https://i.stack.imgur.com/DpQfA.png)
2.NSWindow
设置好后,是时候做ContentView()
⤵︎
在这里您只想创建一个包装器NSVisualEffectView
并将其添加为背景。然后确保从视图中移除安全区域!这可以确保消除标题栏在视图中占用的任何空间。
import SwiftUI
struct ContentView: View {
var body: some View {
Text("Hello, World!")
.frame(maxWidth: .infinity, maxHeight: .infinity)
.background(VisualEffectView(material: .popover, blendingMode: .behindWindow))
// Very important! (You could technically just ignore the top so you do you)
.edgesIgnoringSafeArea(.all)
}
}
/// Takes the image directly behind the window and uses that to create a blurred material. It can technically be added anywhere but most often it's used as a backing material for sidebars and full windows.
struct VisualEffectView: NSViewRepresentable {
let material: NSVisualEffectView.Material
let blendingMode: NSVisualEffectView.BlendingMode
func makeNSView(context: Context) -> NSVisualEffectView {
let visualEffectView = NSVisualEffectView()
visualEffectView.material = material
visualEffectView.blendingMode = blendingMode
visualEffectView.state = NSVisualEffectView.State.active
return visualEffectView
}
func updateNSView(_ visualEffectView: NSVisualEffectView, context: Context) {
visualEffectView.material = material
visualEffectView.blendingMode = blendingMode
}
}
此时,您的视图应该看起来像您想要的那样,没有任何负面影响!享受 <3 (如果您对此解决方案有任何问题,请发表评论!)
![在此处输入图像描述](https://i.stack.imgur.com/v8enY.jpg)
资源
感谢@eonil 以这种巧妙的方式保持圆角。没有这个答案就想不通⤵︎
https://stackoverflow.com/a/27613308/13142325
感谢 lukakerr 制作了这个 NSWindow 样式列表!
https://github.com/lukakerr/NSWindowStyles