LoginSignup
4
5

[Swift] Macアプリで常に最前面に表示する方法

Last updated at Posted at 2020-04-06

はじめに

タイトルに示す通りのことを実現したくて「常に最前面 MacApp」でググったら、クリアメモリさんの『【Swift】常に最前面に表示されるOSXアプリの作り方』のページがヒットしました。この記事に書いてある手順で無事に実現できたのですが、OS他のバージョンが上がっており多少の変更が必要でしたので、元記事からの変更点をまとめておきます。
ほとんどはコンパイルエラーが出て教えてくれますが、元記事への恩返しの意味です。

前提とする環境

当方の環境(執筆時点);

  • maxOS Catalina version 10.15.3
  • Xcode version 11.1 (11E148)
  • Apple Swift version 5.2 (swiftlang-1103.0.32.1 clang-1103.0.32.29)

変更点

AppDelegate.swift

「Stay in Front」メニューをクリックした時の、チェックオン/オフのトグル処理のコードにおいて、NSMenuItem.stateの値が変更になっています。

元記事のコード
func toggleMenuChecked(){
    if stayInFrontMenu.state == NSOnState {
        stayInFrontMenu.state = NSOffState
    }else if stayInFrontMenu.state == NSOffState{
        stayInFrontMenu.state = NSOnState
    }
}
新しいコード
func toggleMenuChecked() {
    if stayInFrontMenu.state == .on {   
        stayInFrontMenu.state = .off
    } else if stayInFrontMenu.state == .off {
        stayInFrontMenu.state = .on
    }
}

WindowController.swift

実際にウィンドウを最前面に設定する処理のコードにおいてNSWindow.Levelの値が変更になっています。

元記事のコード
func stayInFront(){
    let normalWindow = Int(CGWindowLevelForKey(.normalWindow))
    let floatingWindow = Int(CGWindowLevelForKey(.floatingWindow))

    if window?.level == normalWindow{
        window?.level = floatingWindow
    }else if window?.level == floatingWindow{
        window?.level = normalWindow
    }
}   
新しいコード
func stayInFront() {
    if window?.level == .normal {
        window?.level = .floating
    } else if window?.level == .floating {
        window?.level = .normal
    }
}

WindowController.swift (2箇所目)

NotificationCenterのオブザーバから呼び出されるメソッドに@objcattributeが必要です。1 2

元記事のコード
func nCenter(notification: NSNotification) {
    stayInFront()
}
新しいコード
@objc
func nCenter(notification: NSNotification) {
    stayInFront()
}

その他

変更点ではありませんが、コンパイルエラーが出ないので気付きにくい点として;

新しく「WindowController」というクラスを作成し、ストーリーボードで設定してあります。
この工程は省くので、各自設定しておいてください。

下図の様にカスタムクラスを設定する必要があります。これを忘れると_WindowController_が機能しません期待通りに動きません。
スクリーンショット

終わりに

元記事では、他にも_Outlet_や_Action_の接続手順も省略しています。もしこの記事をご覧の方で、これらの手順も知りたい方は、コメントいただければ追加いたします。

2023.7.18追記
SwiftUIで書いたMac Catalystアプリでの実装方法を、↓こちらに公開しました。

  1. なぜ@objcが必要なのか、こちらに説明があります。

  2. @objc他のSwiftのattributeについてはこちらに説明があります。

4
5
4

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
5