トップ 最新 追記

Cocoa練習帳

iOS/iPhone/iPad/watchOS/tvOS/MacOSX/Android プログラミング, Objective-C, Cocoa, Swiftなど

2012|01|02|03|04|05|06|07|08|09|10|11|12|
2013|01|02|03|04|05|06|07|08|09|10|11|12|
2014|01|02|03|04|05|06|07|08|09|10|11|12|
2015|01|02|03|04|05|06|07|08|09|10|11|12|
2016|01|02|03|04|05|06|07|08|09|10|11|12|
2017|01|02|03|04|05|06|07|08|09|

2017-04-03 [macOS]ヘルパ・オブジェクト

今回は、ヒレガス本の日本語版初版のヘルパ・オブジェクトの章。サンプルは、前回のものの拡張だ。

最新の開発環境との違いが出る原因の一つが、今回もStoryboard。

ヒレガス本で説明されている、オブジェクト関連図は以下のとおり。

旧オブジェクト関連図

以前のMyDocumentの部分、Storyboardを利用した場合、NSViewControllerが間に入るため、Viewに関連するコードはViewControllerに、モデル管理のコードはDocumentに、とした。

新オブジェクト関連図

Objective-Cではキー値コーディングを活用するのが賢明で、ヒレガス本では動的な記述をされていた。Swift時代、Swiftyな感覚だと異なる方法が選択されると思うが、Swiftだとどうなるのか試してみたかったので、したがってみた。

    /* カラム:行に表示するインスタンスを返す */
    func tableView(_ aTableView: NSTableView,
                   objectValueFor tableColumn: NSTableColumn?,
                   row: Int) -> Any? {
        let identifier = tableColumn?.identifier
        let person = myDocument?.employees[row]
        return person?.value(forKey: identifier!)
    }
    
    /* 入力されたインスタンスを受け取る */
    func tableView(_ aTableView: NSTableView,
                   setObjectValue object: Any?,
                   for tableColumn: NSTableColumn?,
                   row: Int) {
        let identifier = tableColumn?.identifier
        let person = myDocument?.employees[row]
        person?.setValue(object, forKey: identifier!)
    }

最後にはまったところ。最新の環境でテーブルビューを作成すると、View Basedとなるが、ヒレガス本はCell Based。Cell Basedにすれば動くのだが、せっかくなので、View Basedに挑戦。NSTableViewDelegateの対応が必要になる。

これがCell Basedの場合。

    func tableView(_ aTableView: NSTableView,
                   objectValueFor tableColumn: NSTableColumn?,
                   row: Int) -> Any? {
        let identifier = tableColumn?.identifier
        let person = myDocument?.employees[row]
        return person?.value(forKey: identifier!)
    }

View Based<だと以下となる。/p>

    func tableView(_ tableView: NSTableView, viewFor tableColumn: NSTableColumn?, row: Int) -> NSView? {
        let cell = tableView.make(withIdentifier: (tableColumn?.identifier)!, owner: self) as! NSTableCellView
        let person = myDocument?.employees[row]
        if let tcol = tableColumn {
            let identifier = tcol.identifier
            if(identifier == "personName") {
                cell.textField?.stringValue = person?.value(forKey: identifier) as! String
            }
            else if(identifier == "expectedRaise") {
                cell.textField?.floatValue = person?.value(forKey: identifier) as! Float
            }
        }
        return cell
    }

_ ソースコード

GitHubからどうぞ。
https://github.com/murakami/workbook/tree/master/mac/RaiseMan - GitHub

_ 【Cocoa練習帳】

http://www.bitz.co.jp/weblog/
http://ameblo.jp/bitz/(ミラー・サイト)

トップ 最新 追記