Learn Swift / viva Cocoa


Learn Swift / 第4章  コーディング


このコーナーでは、Swift による、Mac OS X アプリケーションの作成方法を、説明しています。

2016年1月17日

home  目次  前へ  次へ  mail


ViewController.swift

 コーディングしやすいように、エディタエリアを、スタンダードエディタに切り替えます。次の図を参考にして、プロジェクト画面の右上の、スタンダードエディタ (Standard Editor) ボタンをクリックしてださい。エディタエリアが一つの画面に戻ります。

 次に、ナビゲータエリアで "ViewController.swift" を選びます。拡張子 .swift のファイルが、Swift で書かれたコードファイルです。エディタ画面に、ViewController.swit のコードが表示されます。この、ViewController.swit というコードファイルが、Hello アプリケーションのビュー (view、見た目) を、コントロールしているコードファイルです。


コード説明


//
//  ViewController.swift
//  Hello
//
//  Created by Your Name on 2016/01/14.
//  Copyright © 2016年 Your Company. All rights reserved.
//

 コードの中で、ダブルスラッシュ // で始まる部分は、コメントと呼ばれます。コメントは、コードの中にメモを残すために使われます。コメントに、何が記述されていても、プログラムには、影響しません。

import Cocoa

 import キーワードで、Apple によって、準備されている、膨大なコードを読み込んでいます。これによって、私たちは、追加のコードを記述するだけで、アプリケーションを作ることができます。なお、Swift では、アルファベットの大文字と小文字は区別されます。

class ViewController: NSViewController {
	
}

 ビューをコントロールするための、ViewController というクラスを定義しています。オブジェクト指向プログラミングでは、ある特定の目的のために使われるコードの固まりを、クラス (class) と呼ばれる単位にまとめます。クラスの中身は、"{" と "}" の間に記述する決まりになっています。

 ところで、アプリケーションのビューをコントロールするというのは、実際には大変な作業です。その大変な作業のほとんどを、Apple が用意している、NSViewController というクラスがになっています。

ViewController: NSViewController

 という記述は、この NSViewController というクラスのすべて受け継いだ、ViewController という新しいクラスを作ることを意味しています。このような場合、元になったクラスをスーパークラス (super class、もしくは親クラス) と呼び、新しく作られたクラスをサブクラス (sub class、もしくは子クラス) と呼びます。

    @IBOutlet weak var label: NSTextField!
    @IBAction func pushedButton(sender: AnyObject) {
    }

 クラスの中身は、インデント (indent、字下げ) して記述します。字下げしなくてもプログラムには影響しませんが、見やすくするためにインデントされています。

@IBOutlet weak var label: NSTextField!

 コードとラベルとのアウトレット接続を表しています。var というキーワードが、このコードが、変数 (variable) であることを表しています。変数については、 第6章  定数と変数 で説明します。

@IBAction func pushedButton(sender: AnyObject)

 コードとボタンとのアクション接続を表しています。func というキーワードが、このコードが ファンクション (function、関数) であることを表しています。ファンクションは、何かの作業をします。作業の中身は、{ と } の間に記述します。そして、{ と } の間はインデントして記述します。ここでは、ボタンがクリックされた時の働きを記述しますが、どのように記述するかは、のちほど説明します。

    override func viewDidLoad() {
        super.viewDidLoad()

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

 viewDidLoad というファンクションを定義しています。冒頭に override と付いているのは、スーパークラスの NSViewController クラスで、定義されているファンクションであることを、表しています。super.viewDidLoad() では、そのスーパークラスの viewDidLoad を実行しています。 そして、// Do any additional setup after loading the view. とコメントされているように、この位置に、独自のコードを記述することになります。

 この、viewDidLoad ファンクションは、アプリケーションのビューの読み込みが、完了した時に、自動的に実行されます。

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

 representObject という、プロパティ (property、属性) を定義しています。ファンクションが、クラスの中での作業を定義しているのに対して、プロパティは、クラスの中で使われるデータを定義しています。クラスの冒頭に記述されている、@IBOutlet weak var label: NSTextField! も、プロパティになります。

 representedObject プロパティは、ビュー間での値の受け渡しに使われます。そしてこのプロパティは、Computed プロパティと呼ばれるものです。今回は使いません。詳しい説明は省略いたします。


pushedButton ファンクション

 では、pushedButton ファンクションの中身を記述します。次のリストの太字部分が、追加するコードです。

    @IBAction func pushedButton(sender: AnyObject) {
        label.stringValue = "こんにちは"
    }

 コーディングが終わりましたら、Hello アプリケーションを実行してください。ウィンドウが表示されましたら、ボタンをクリックしてください。ラベルに "こんにちは" と表示されます。

label.stringValue = "こんにちは"

 label は、アウトレットで接続したラベルを表しています。そのラベルの文字列 (stringValue) を、"こんにちは" という文字列で、設定しなおしています。= という記号は、Swift では、イコールではなく、代入 (置き換える) という意味になります。設定する文字列は " と " で囲みます。

 ラベルは、NSTextField という、Apple が用意しているクラスです。このコードでは、NSTextField クラスの、stringValue というプロパティが保持しているデータを、"こんにちは" という文字列で設定しなおしています。Swift では、文字列を " と " で囲んで表します。Swift ではこのように、クラスのプロパティを、クラス名.プロパティ名、というふうに . (dot、ドット) を使って表します。




 Hello アプリケーションは、今のままでは、一度ボタンをクリックしたあとは、なんの反応もしなくなります。ボタンをクリックするたび反応するように変えたいと思います。次のリストのように、class ViewController: NSViewController の次の行に、コードを追加してください。・・・は、コードを省略していることを表しています。・・・は、記述しないでください。

    class ViewController: NSViewController {
        var isHello:Bool = true
    ・・・

 var は値の変わるプロパティであることを表しています。値が変わらない場合は、let と記述します。isHello は、プロパティの名前です。この名前も命名規則に従って、自由に決めることができます。命名規則については、 第6章  定数と変数 の「命名規則」節で説明します。 :Bool は、このプロパティが、Bool という型であることを定義しています。

 型とは、プロパティが保持しているデータが、どのようなもであるかを表しています。Bool 型は、Yes を表す true と、No を表す false という二つの値を保持できます。そして次の、= true で、isHello プロパティに、true という値を設定しています。今回のように、プロパティに初めて値を設定するときのことを初期化といいます。 コードからビューに指令を出すための接続をアウトレット (Outlet) と呼び




 次に、pushedButton ファンクションのコードを、次のリストのように変更します。なお、ファンクションは、メソッド (method、方式・方法) と呼ばれることもあります。今後はメソッドという呼び方をする場合があります。

    @IBAction func pushedButton(sender: AnyObject) {
        if isHello {
            label.stringValue = "こんにちは"
            isHello = false
        } else {
            label.stringValue = "Hello"
            isHello = true
        }
    }
if isHello {

 if は、文字どおり「もしも」 という意味になります。if に続けて、true か false を表す式を記述します。ここでは、isHello を記述しています。そして式が true だった場合の処理を、 { と } の間に記述します。

} else {

 if isHello が、false だった場合の処理を、else { } の間に記述します。

 コーディング終わりましたら、Hello アプリケーションを実行してください。ボタンをクリックするたびに、ラベルの文字列が、"こんにちは" と "Hello" で入れ替わります。




 さらにラベルを、もう少し、華やかにしてみます。次のリストのように、pushedButton メソッドに、コードを追加してください。

    @IBAction func pushedButton(sender: AnyObject) {
        if isHello {
            label.stringValue = "こんにちは"
            label.backgroundColor = NSColor.greenColor()
            label.textColor = NSColor.whiteColor()
            isHello = false
        } else {
            label.stringValue = "Hello"
            label.backgroundColor = NSColor.whiteColor()
            label.textColor = NSColor.greenColor()
            isHello = true
        }
    }
label.backgroundColor = NSColor.greenColor()

 ラベルの backgroundColor プロパティに、Apple が用意している NSColor クラスの greenColor() メソッドによって作成される、緑色を設定しています。Swift では、クラスのメソッドも、クラス名.メソッド名というぐあいに、. (dot、ドット) を使ってアクセスします。今回はこの結果、ラベルの背景色に緑色が設定されます。

label.textColor = NSColor.whiteColor()

 ラベルの textColor プロパティに、NSColor クラスの whiteColor() メソッドによって作成される、白色を設定しています。今回はこの結果、ラベルの文字色に白色が設定されます。

 コーディングが終わりましたら、Hello アプリケーションを実行してください。ボタンをクリックするたびに、ラベルの背景色が、緑色と白色で入れ替わり、それに合わせて、文字の色が、白色と緑色に入れ替わります。


ビューの初期値

 Hello アプリケーションが起動した時に、ラベルには、"Label" と表示され、文字の色も黒色です。このような、ビューが最初に表示された時の初期値は、どうすれば良いのでしょうか?

 一つの方法としては、ストリーボードのアトリビュートインスペクタで、ラベルの文字列を "Hello" に設定して、文字の色も変えておく方法が考えらます。Hello アプリケーションの場合は、ストーリーボードで設定しておくことが可能です。しかしすべての場合で、ストーリーボードで初期値が設定できるわけではありません。そういう場合のために、viewDidLoad メソッドが用意されています。

 viewDidLoad メソッドを、次のリストのように変更してください。

    override func viewDidLoad() {
        super.viewDidLoad()

        label.stringValue = "Hello"
        label.textColor = NSColor.greenColor()
        isHello = true
    }

 ここでは、ラベルの文字や文字色だけではなく、isHello プロパティにも、true を設定しています。isHello プロパティは、ViewController クラスの冒頭で定義するときにも true を設定しましたが、コーディングの慣習としては、定義時に false を設定して、ここで true を設定したほうが本格的です。

 コーディングが終わりましたら、Hello アプリケーションを実行してください。起動直後からラベルに、Hello と緑色で表示されます。

 ViewController.swift の全コードは、次のコードリストのようになります。冒頭のコメントは省略しています。

import Cocoa

class ViewController: NSViewController {
    var isHello:Bool = false

    @IBOutlet weak var label: NSTextField!
    @IBAction func pushedButton(sender: AnyObject) {
        if isHello {
            label.stringValue = "こんにちは"
            label.backgroundColor = NSColor.greenColor()
            label.textColor = NSColor.whiteColor()
            isHello = false
        } else {
            label.stringValue = "Hello"
            label.backgroundColor = NSColor.whiteColor()
            label.textColor = NSColor.greenColor()
            isHello = true
        }
    }
    override func viewDidLoad() {
        super.viewDidLoad()

        label.stringValue = "Hello"
        label.textColor = NSColor.greenColor()
        isHello = true
    }

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


}


AppDelegate.swift

 Hello アプリケーションは、ウィンドウを閉じても、終了することはありません。通常、Hello アプリケーションのように小さくて、ウィンドウが一つだけのアプリケーションの多くは、ウィンドウを閉じると、アプリケーションも終了するように設定されています。

 このような、アプリケーションの起動・終了にかかわる設定は、AppDelegate.swift に記述します。さきほどは、ビューが表示された時の設定を、ViewController.swift に記述しましたが、アプリケーションの起動と、ビューの表示は同じではありません。ビューを表示せずに起動するアプリケーションも存在します。

 プロジェクト画面のネビゲーションエリアで、AppDelegate.swift を選んでください。エディタエリアが AppDelegate.swift に変わります。

 次のリストのように、AppDelegate クラスに、applicationShouldTerminateAfterLastWindowClosed ファンクションを記述してください。

class AppDelegate: NSObject, NSApplicationDelegate {

    func applicationShouldTerminateAfterLastWindowClosed(sender: NSApplication) -> Bool {
        return true
    }
    
    ・・・
class AppDelegate: NSObject, NSApplicationDelegate {

AppDelegate クラスの定義を始めています。: (colon、コロン) の次にスーパークラスを指定して、, (comma、コンマ) の次に、プロトコルと呼ばれるものを指定しています。プロトコルについては、パート2として予定している、シンタックス (syntax、構文) で詳しく説明します。

func applicationShouldTerminateAfterLastWindowClosed(sender: NSApplication) -> Bool {

 applicationShouldTerminateAfterLastWindowClosed ファンクションを実装しています。このメソッドは、アプリケーションで表示している、最後のウィンドウを閉じた時に実行されます。( ) の間の sender: NSApplication は、引数と呼ばれるものです。そして、-> Bool は、戻り値と呼ばれるものです。この二つについては、パート2のシンタックスで説明します。なおここでは、ファンクションの定義とは言わずに、ファンクションの実装と言いました。ファンクションの中身、{ と } の間を記述することを、実装といいます。

return true

 return は、ファンクションから値を返して、ファンクションを終了するときに使われます。ここでは、true を返して、ファンクションを終了しています。Hello アプリケーションは、このファンクションから true が戻ってくることによって、アプリケーションの最後のウィンドウを閉じたときに、Hello アプリケーションを終了することになります。

 コードの記述が終了しましたら、Hello アプリケーションを実行してみてください。ウィンドウのクローズボックスをクリックして、ウィンドウを閉じると、Hello アプリケーションも終了します。

 AppDelegate.swift の全コードは、次のコードリストのようになります。冒頭のコメントは省略しています。

import Cocoa

@NSApplicationMain
class AppDelegate: NSObject, NSApplicationDelegate {

    func applicationShouldTerminateAfterLastWindowClosed(sender: NSApplication) -> Bool {
        return true
    }

    func applicationDidFinishLaunching(aNotification: NSNotification) {
        // Insert code here to initialize your application
    }

    func applicationWillTerminate(aNotification: NSNotification) {
        // Insert code here to tear down your application
    }


}
 


お疲れ様でした。

 この章で、パート1を終了し、第5章からは、パート2として、Swift のシンタックス (syntax、構文) を説明したいと思います。


home  目次  前へ  次へ  mail


無断転載禁止
Copyright 2016. vivacocoa.jp All right reserved.