Cocoa版Hello World作成の続きです。今回は、ウインドウの最小サイズと最大サイズを設定します。また、ウインドウをスクリーンの中央に配置する処理を、HelloWindowContorller
クラスに追加します。
この記事では前回作成したサンプルコードを使用します。前回作成したサンプルコードは次の記事からダウンロードできます。

ウインドウの最小サイズ・最大サイズの設定
ウインドウの最小サイズ・最大サイズはコード設定する方法と、Storyboardファイル内で設定する方法があります。この記事ではコードで設定する方法を解説します。どちらの方法でも構わないのですが、次のような理由でコード定義にしました。
- 値を決定するときに試行錯誤が簡単。
- 将来のバージョンなどで値を変更していったときに変更履歴を追うのが容易になる。
最小値・最大値を設定するコードを追加する
Storyboardファイルからウインドウを読み込むと、AppKitはNSWindowController.windowDidLoad()
メソッドを実行します。windowDidLoad()
メソッドはウインドウの初期化処理を行うためのデリゲートメソッドです。このメソッド内で最小値・最大値を設定します。
次のようにコードを追加します。
import Cocoa
class HelloWindowController: NSWindowController {
let minWindowWidth: CGFloat = 200
let minWindowHeight: CGFloat = 150
let maxWindowWidth: CGFloat = 1200
let maxWindowHeight: CGFloat = 900
override func windowDidLoad() {
super.windowDidLoad()
window?.minSize = CGSize(width: minWindowWidth,
height: minWindowHeight)
window?.maxSize = CGSize(width: maxWindowWidth,
height: maxWindowHeight)
}
}
次のスクリーンキャプチャは最小サイズにしているときのスクリーンキャプチャです。

ウインドウの取得
AppKitのウインドウはNSWindowController.window
プロパティに入っています。
open var window: NSWindow?
最小サイズ
ウインドウの最小サイズはNSWindow.minSize
プロパティに設定します。
open var minSize: NSSize
最大サイズ
ウインドウの最大サイズはNSWindow.maxSize
プロパティに設定します。
open var maxSize: NSSize
カーソルの制御
サイズ変更可能なウインドウの場合、ウインドウの角やフレームなどにカーソルを持って行くと、カーソルが自動的にリサイズ可能なことを示すように変化します。AppKitでは何もしなくても、macOSの標準的なカーソル制御を行ってくれます。
例えば、次のスクリーンキャプチャはウインドウサイズを広げることも縮めることもできる状態のときです。

最小サイズのときは、これ以上縮小できないことを示すカーソルになります。

最大サイズのときは、これ以上を広げることができないことを示すカーソルになります。

ウインドウを中央に配置する
ウインドウを中央に配置する処理を追加します。
コードの追加
単純に考えると、スクリーンサイズとウインドウサイズを元に、中央に配置する座標を計算するという処理になります。
NSWindow
クラスにはウインドウを中央に移動するメソッドがあるので、計算しなくても、用意されているメソッドを使うだけで中央に配置できます。
次のようにコードを変更します。
import Cocoa
class HelloWindowController: NSWindowController {
let minWindowWidth: CGFloat = 200
let minWindowHeight: CGFloat = 150
let maxWindowWidth: CGFloat = 1200
let maxWindowHeight: CGFloat = 900
override func windowDidLoad() {
super.windowDidLoad()
window?.minSize = CGSize(width: minWindowWidth,
height: minWindowHeight)
window?.maxSize = CGSize(width: maxWindowWidth,
height: maxWindowHeight)
window?.makeKeyAndOrderFront(nil)
window?.center()
}
}
追加したコードは次の部分です。
window?.makeKeyAndOrderFront(nil)
window?.center()
ウインドウリストとキーウインドウについて
macOSではスクリーンに表示されているウインドウを管理しているウインドウリストがあります。
windowDidLoad()
メソッドが実行されている時点では、ウインドウリストにウインドウが入っていないので、スクリーンにはウインドウは表示されません。
この状態でcenter()
メソッドを使っても、どのスクリーンに対して中央なのかが決まらないので、center()
メソッドが動きません。
そこで、NSWindow.makeKeyAndOrderFront()
メソッドを使用します。makeKeyAndOrderFront()
メソッドは次のような処理を行います。
- 先頭のスクリーンにウインドウを移動する。
- ウインドウをキーウインドウに変更する
- ウインドウを表示する
キーウインドウとは?
スクリーンには複数のアプリが同時に起動し、各アプリは複数のウインドウを持っています。キーボードからキー入力を行うと、最前面にあるウインドウがキーダウンイベントを受け取り、キー入力を処理します。このウインドウのことを「キーウインドウ」と呼びます。
微妙に中央ではない?
center()
メソッドで配置されたウインドウが微妙に中央ではないことに気がつきましたか?水平方向は中央揃えになっていますが、若干、上方向にずれて表示されます。
これは、不具合ではありません。
人間の視覚は、完全な中央よりも若干上にずれた位置の方が見やすく、気がつきやすいため、このような仕様になっています。
サンプルコードのダウンロード
今回の記事で作成したサンプルコードはこちらからダウンロードできます。