在针对Cocoa应用程序的Objective-C中,可以使用这种方式使窗口始终位于顶部吗?
如何用Swift实现同样的目标?
self.view.window?.level = NSFloatingWindowLevel
导致构建错误Use of unresolved identifier 'NSFloatingWindowLevel'
答案 0 :(得分:72)
要更改窗口级别,您无法在viewDidload中执行此操作,因为视图的窗口属性将始终为nil,但可以覆盖viewDidAppear方法或IBAction方法:
Swift 1
override func viewDidAppear() {
super.viewDidAppear()
view.window?.level = Int(CGWindowLevelForKey(kCGFloatingWindowLevelKey))
}
Swift 2
view.window?.level = Int(CGWindowLevelForKey(.FloatingWindowLevelKey))
Swift 3
view.window?.level = Int(CGWindowLevelForKey(.floatingWindow))
Swift 4
最后他们修复了奇怪的语法:
view.window?.level = .floating
答案 1 :(得分:3)
我更喜欢这种方式。这会忽略所有其他活动应用,并使您的应用程序提前。
override func viewWillAppear() {
NSApplication.sharedApplication().activateIgnoringOtherApps(true)
}
答案 2 :(得分:0)
尽管其他答案在技术上都是正确的-当您的应用将要退出或确实退出时,将window
级别设置为.floating
不会生效。
.floating
意味着您正在使用的应用程序位于所有窗口的顶部,而不是所有应用程序窗口的顶部。
是的,您还可以设置其他级别,例如 kCGDesktopWindowLevel ,您可以也不应设置为迅速使窗口浮于水面。
它们都不会改变您的窗口将位于焦点和活动应用程序窗口后面的事实。为了避免这种情况,我选择观察应用程序是否退出活动通知并采取相应措施。
var observer : Any;
override func viewDidLoad() {
super.viewDidLoad()
observer = NotificationCenter.default.addObserver(
forName: NSApplication.didResignActiveNotification,
object: nil,
queue: OperationQueue.main ) { (note) in
self.view.window?.level = .floating;
// you can also make your users hate you, to take care, don't use them.
//NSApplication.shared.activate(ignoringOtherApps: true)
//self.view.window?.orderFrontRegardless();
}
}
另一种方法是将NSWindow子类化,并始终返回.floating来覆盖属性.level,但是上面的代码工作量较小,并且将控制权保留在要设置窗口浮动的位置。