AppKitでコントロールの値を読み書きする方法(アウトレットについて) | macOSアプリの作り方

前回はボタンをクリックしたときにアクションを実行するという処理を実装しました。ボタンによるアクションは一般的なアプリで共通する基本的な事柄の一つです。同様にアプリ開発で共通する事柄の一つに、コントロールの値の読み書きがあります。

コントロールというのは、ボタンやラベル、テキストフィールドなどビューの一種です。今回はテキストフィールドに入力された文字列を読み込み、ラベルに新しい文字列を設定するという機能の実装を通して、AppKitでのコントロールの値の読み書き方法を解説します。

目次

プロジェクトの作成

新しいmacOSアプリ用のプロジェクトを作成してください。プロジェクトの名前はCocoaHelloWorld2とします。プロジェクトの作成方法については、次の記事を参照してください。

ユーザーインターフェイスの作成

プロジェクトを作成したら早速UIを作成します。Main.storyboardのView Controller Sceneを編集し、次のスクリーンキャプチャのような画面を作成します。

作成するユーザーインターフィエス
作成するユーザーインターフィエス

ラベルの作成

「Hello World」と書かれている部分は「Label」を配置します。次のように操作して作成します。

(1) 「Library」ボタンをクリックし、「Library」ウインドウから「Label」をドラッグ&ドロップして追加します。

(2) ラベルの文字列を「Hello World」に変更します。

(3) 「Font」を「Text Style – Large Title」に設定します。

(4) オートレイアウトを以下のようになるように設定します。

項目 設定
X座標 左右中央
Y座標 上から固定
幅 固定
高さ 固定
左右中央揃えに設定する
左右中央揃えに設定する
上側の余白、幅、高さを設定する
上側の余白、幅、高さを設定する

名前の入力欄

中央に表示された名前の入力欄は「Text Field」を配置します。次のように操作して作成します。

(1) 「Library」ウインドウから「Text Field」をドラッグ&ドロップします。

Text Field
Text Field

(2) 幅を調整します。

(3) 「Attributes」インスペクタの「Placeholder」に「Your Name」と入力します。「Placeholder」はプレイスホルダー文字列を設定します。プレイスホルダー文字列は、テキストフィールドに何も入力されていないときに、テキストフィールドに薄く表示される文字列のことです。

Placeholderを設定する
Placeholderを設定する

(4) オートレイアウトを次の表のようになるように設定します。

項目 設定
X座標 左右中央
Y座標 上下中央
幅 固定
高さ 固定
左右上下中央に配置する
左右上下中央に配置する
幅と高さを固定する
幅と高さを固定する

「Change Name」ボタン

「Change Name」と書かれているボタンは「Push Button」を配置します。次のように操作します。

(1) 「Library」ウインドウから「Push Button」を配置します。

(2) ボタンをダブルクリックしてタイトルを「Change Name」に変更します。

(3) オートレイアウトの設定を次の表のように設定します。

項目 設定
X座標 左右中央
Y座標 「Text Field」から固定
幅 固定
高さ 固定
左右中央に設定する
左右中央に設定する
幅、高さ、Y座標を設定する
幅、高さ、Y座標を設定する

アウトレットを作成する

Storyboard内で作成したいビューに配置したオブジェクトをコードから参照するには、アウトレットを作成します。アウトレットはSwiftでは@IBOutletというアトリビュートを付けたプロパティです。

アウトレットとStoryboard内のオブジェクトとの間でコネクションを設定すると、アウトレットにStoryboard上のオブジェクトのインスタンスが代入されます。

名前の入力欄とラベルへのアウトレットを作成する

名前の入力欄とラベルへのアウトレットを作成します。ラベルとテキストフィールドはAppKitでは、NSTextFieldクラスです。コントロールに対応するクラスが何であるかは「Library」ウインドウに表示されています。

「Label」のクラスが「NSTextField」であることが分かる
「Label」のクラスが「NSTextField」であることが分かる
「Text Field」のクラスが「NSTextField」であることが分かる
「Text Field」のクラスが「NSTextField」であることが分かる

ViewController.swiftに次のようにアウトレットを定義します。

import Cocoa

class ViewController: NSViewController {
    
    @IBOutlet var messageLabel: NSTextField!
    @IBOutlet var nameField: NSTextField!

    override func viewDidLoad() {
        super.viewDidLoad()

        // Do any additional setup after loading the view.
    }

    override var representedObject: Any? {
        didSet {
        // Update the view, if already loaded.
        }
    }


}

アウトレットとコネクションを接続する

messageLabelプロパティと「Hello World」と書かれたラベル、nameFieldとテキストフィールドとをコネクションで接続します。次のように操作します。

(1) Main.storyboardを開きます。

(2) 「View Controller」からビューに配置した「Hello World」ラベルからまで、コントロールキーを押しながら、または、右マウスボタンでドラッグ&ドロップして、コネクションを接続します。

コネクションを張る
コネクションを張る

(3) 「Outlets」から「messageLabel」を選択します。この操作で、messageLabelと配置したラベルとの間でコネクションが接続され、Main.storyboardが読み込まれたときに、プロパティmessageLabelにラベルのオブジェクトが代入されます。

(4) 手順(2)と(3)と同様に操作して、nameFieldプロパティと名前入力用のテキストフィールドとの間にコネクションを接続します。

ボタンのアクションを作成する

「Change Name」ボタンがクリックされたときに実行するアクションを実装します。ViewController.swiftに処理を実装します。次のようにコードを追加します。

import Cocoa

class ViewController: NSViewController {
    
    @IBOutlet var messageLabel: NSTextField!
    @IBOutlet var nameField: NSTextField!

    override func viewDidLoad() {
        super.viewDidLoad()

        // Do any additional setup after loading the view.
    }

    override var representedObject: Any? {
        didSet {
        // Update the view, if already loaded.
        }
    }

    @IBAction func changeName(_ sender: Any?) {
        // 入力された文字列を取得する
        let name = nameField.stringValue
        
        // 新しい文字列を作成する
        let message = "Hello \(name)"
        
        // ラベルを更新する
        messageLabel.stringValue = message
    }
}

アクションや実装したコードをボタンで実行されるように設定する方法については次の記事を参照してください。

ラベルの大きさを変更する

アプリを実行します。名前を入力して「Change Name」ボタンをクリックするとラベルの文字列が変わります。問題ないように思われますが、長い名前を入力してみましょう。

「hi」が表示されていない
「hi」が表示されていない

元々の「Hello World」よりも長いと表示できません。動的に変更する方法も一つですが、ここでは、左右の余白を固定化して、ウインドウサイズに合わせてラベル幅が変わるようにしてみましょう。

(1) Main.storyboardを開きます。

(2) 「Hello World」ラベルを選択し、「Size」インスペクタを開きます。

(3) 「Width Equals: 130」と「Height Equals: 31」を選択し、「Delete」キーを押して削除します。

幅と高さのコンストレイントを削除する
幅と高さのコンストレイントを削除する

(4) ラベルの幅をガイドが表示されるところまで広げます。

ラベルの幅を広げる
ラベルの幅を広げる

(5) 左右の余白のコンストレイントを設定し、「Add 2 Constraints」をクリックします。

左右の余白のコンストレイントを設定する
左右の余白のコンストレイントを設定する

(6) アトリビュートインスペクタで「Alignment」を中央揃えに設定します。

中央揃えに設定する
中央揃えに設定する

動作テスト

完成したアプリを実行してみましょう。長い文字列やウインドウサイズによる表示の違いも確認しましょう。

動作テスト
動作テスト

サンプルコードのダウンロード

今回の記事で作成したサンプルコードはこちらからダウンロードできます。

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

この記事を書いた人

Akira Hayashi (林 晃)のアバター Akira Hayashi (林 晃) Representative(代表), Software Engineer(ソフトウェアエンジニア)

アールケー開発代表。画像処理技術とAppleプラットフォーム開発を専門とするソフトウェア開発者。ソフトウェアの受託開発、技術書執筆、技術指導・セミナー講師。note, LinkedIn

目次