我正在尝试将SwiftUI视图用作MacOS上的NSCursor。
使用SwiftUI,我正在构建一个视图,然后使用NSHostingView
将该视图转换为NSView。现在,我尝试通过NSImage
将其转换为NSBitmapImageRep
。由于某些原因,在设置断点时检查变量时,我总是得到一个空的png。
(目前,光标的设置已在AppDelegate
中完成,因为我目前正试图使其工作。)
class AppDelegate: NSObject, NSApplicationDelegate {
var window: NSWindow!
func applicationDidFinishLaunching(_ aNotification: Notification) {
// Create the SwiftUI view that provides the window contents.
let contentView = ContentView()
let contentRect = NSRect(x: 0, y: 0, width: 480, height: 480)
// Create the window and set the content view.
window = NSWindow(
contentRect: contentRect,
styleMask: [.titled, .closable, .miniaturizable, .resizable, .fullSizeContentView],
backing: .buffered, defer: false)
window.center()
window.setFrameAutosaveName("Main Window")
window.contentView = NSHostingView(rootView: contentView)
window.makeKeyAndOrderFront(nil)
let myNSView = NSHostingView(rootView: ContentView()).bitmapImageRepForCachingDisplay(in: contentRect)!
NSHostingView(rootView: ContentView()).cacheDisplay(in: contentRect, to: myNSView)
let myNSImage = NSImage(size: myNSView.size)
myNSImage.addRepresentation(myNSView)
self.window.disableCursorRects()
// var myName = NSImage.Name("ColorRing")
// var myCursorImg = NSImage(named: myName)!
//
// var myCursor = NSCursor(image: myCursorImg, hotSpot: NSPoint(x: 10, y: 10))
var myCursor = NSCursor(image: myNSImage, hotSpot: NSPoint(x: 0, y: 0))
myCursor.set()
}
func applicationWillTerminate(_ aNotification: Notification) {
// Insert code here to tear down your application
}
}
执行注释掉的部分时,我从一个外部png文件获得了鼠标光标。
执行上面显示的代码时,我总是得到一个大小为480x480的空鼠标光标。在调试模式下,我可以看到myNSView
是一个空png。我敢肯定,我会误解文档,因此会滥用cacheDisplay(in:to:)
和bitmapImageRepForCachingDisplay(in:)
。documentation告诉我使用NSBitmapImageRep
中bitmapImageRepForCachingDisplay(in:)
中的cacheDisplay(in:to:)
。但是由于某种原因,我根本无法使它正常工作。
有人知道我在做什么错吗?
回答我自己的问题:
[似乎需要将视图转换为NSImage
的视图必须放在窗口内部。否则,它可能不知道视图在矩形内需要多大。
以下代码对我有用:
func applicationDidFinishLaunching(_ aNotification: Notification) {
// Create the SwiftUI view that provides the window contents.
let contentView = ContentView()
let contentRect = NSRect(x: 0, y: 0, width: 480, height: 480)
// Create the window and set the content view.
window = NSWindow(
contentRect: contentRect,
styleMask: [.titled, .closable, .miniaturizable, .resizable, .fullSizeContentView],
backing: .buffered, defer: false)
window.center()
window.setFrameAutosaveName("Main Window")
window.contentView = NSHostingView(rootView: contentView)
window.makeKeyAndOrderFront(nil)
// CHANGED ----------
let newWindow = NSWindow(
contentRect: contentRect,
styleMask: [.titled, .closable, .miniaturizable, .resizable, .fullSizeContentView],
backing: .buffered, defer: false)
newWindow.contentView = NSHostingView(rootView: contentView)
let myNSBitMapRep = newWindow.contentView!.bitmapImageRepForCachingDisplay(in: contentRect)!
newWindow.contentView!.cacheDisplay(in: contentRect, to: myNSBitMapRep)
// CHANGED ----------
let myNSImage = NSImage(size: myNSBitMapRep.size)
myNSImage.addRepresentation(myNSBitMapRep)
self.window.disableCursorRects()
var myCursor = NSCursor(image: myNSImage, hotSpot: NSPoint(x: 0, y: 0))
myCursor.set()
}
仅两个//CHANGED -----
注释之间的行已更改,这是可行的解决方案。我只是在应用与以前相同的方法之前将视图嵌入窗口中。希望这对以后的人们有所帮助。