保持窗口总是在顶部?

时间:2014-12-10 09:05:37

标签: swift macos swift2 nswindow swift3

在针对Cocoa应用程序的Objective-C中,可以使用这种方式使窗口始终位于顶部吗?

如何用Swift实现同样的目标?

self.view.window?.level = NSFloatingWindowLevel

导致构建错误Use of unresolved identifier 'NSFloatingWindowLevel'

3 个答案:

答案 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,但是上面的代码工作量较小,并且将控制权保留在要设置窗口浮动的位置。