我正在尝试将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:)
。但是出于某种原因,我根本无法使它正常工作。
有人知道我在做什么错吗?
答案 0 :(得分:0)
要回答我自己的问题:
似乎要将一个想要转换为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 -----
注释之间的行已更改。我只是在应用与以前相同的方法之前将视图嵌入窗口中。
希望这对以后的人们有所帮助。