前回はボタンをクリックしたときにアクションを実行するという処理を実装しました。ボタンによるアクションは一般的なアプリで共通する基本的な事柄の一つです。同様にアプリ開発で共通する事柄の一つに、コントロールの値の読み書きがあります。
コントロールというのは、ボタンやラベル、テキストフィールドなどビューの一種です。今回はテキストフィールドに入力された文字列を読み込み、ラベルに新しい文字列を設定するという機能の実装を通して、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」をドラッグ&ドロップします。
(2) 幅を調整します。
(3) 「Attributes」インスペクタの「Placeholder」に「Your Name」と入力します。「Placeholder」はプレイスホルダー文字列を設定します。プレイスホルダー文字列は、テキストフィールドに何も入力されていないときに、テキストフィールドに薄く表示される文字列のことです。
(4) オートレイアウトを次の表のようになるように設定します。
項目 | 設定 |
---|---|
X座標 | 左右中央 |
Y座標 | 上下中央 |
幅 | 固定 |
高さ | 固定 |
「Change Name」ボタン
「Change Name」と書かれているボタンは「Push Button」を配置します。次のように操作します。
(1) 「Library」ウインドウから「Push Button」を配置します。
(2) ボタンをダブルクリックしてタイトルを「Change Name」に変更します。
(3) オートレイアウトの設定を次の表のように設定します。
項目 | 設定 |
---|---|
X座標 | 左右中央 |
Y座標 | 「Text Field」から固定 |
幅 | 固定 |
高さ | 固定 |
アウトレットを作成する
Storyboard内で作成したいビューに配置したオブジェクトをコードから参照するには、アウトレットを作成します。アウトレットはSwiftでは@IBOutlet
というアトリビュートを付けたプロパティです。
アウトレットとStoryboard内のオブジェクトとの間でコネクションを設定すると、アウトレットにStoryboard上のオブジェクトのインスタンスが代入されます。
名前の入力欄とラベルへのアウトレットを作成する
名前の入力欄とラベルへのアウトレットを作成します。ラベルとテキストフィールドはAppKitでは、NSTextField
クラスです。コントロールに対応するクラスが何であるかは「Library」ウインドウに表示されています。
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」ボタンをクリックするとラベルの文字列が変わります。問題ないように思われますが、長い名前を入力してみましょう。
元々の「Hello World」よりも長いと表示できません。動的に変更する方法も一つですが、ここでは、左右の余白を固定化して、ウインドウサイズに合わせてラベル幅が変わるようにしてみましょう。
(1) Main.storyboard
を開きます。
(2) 「Hello World」ラベルを選択し、「Size」インスペクタを開きます。
(3) 「Width Equals: 130」と「Height Equals: 31」を選択し、「Delete」キーを押して削除します。
(4) ラベルの幅をガイドが表示されるところまで広げます。
(5) 左右の余白のコンストレイントを設定し、「Add 2 Constraints」をクリックします。
(6) アトリビュートインスペクタで「Alignment」を中央揃えに設定します。
動作テスト
完成したアプリを実行してみましょう。長い文字列やウインドウサイズによる表示の違いも確認しましょう。
サンプルコードのダウンロード
今回の記事で作成したサンプルコードはこちらからダウンロードできます。