NSCollectionView を Bind するのに少しつまずいたのでメモ。(新しめの記事もなかったので)

環境

  • macOS 10.14.4
  • Xcode 10.2.1
  • Swift 5

やり方

InterfaceBuilder に必要なものを設置

  1. ViewControllerにCollectionViewとArrayControllerを設置
  1. CollectionViewItem の Nib を作成する
  1. 先ほど作成した Nib をカスタマイズする 今回は、Label と ImageView を設置しました。
  1. Object を設置し、CollectionViewItem を追加する
  1. CollectionViewItem の View を先ほど作成した Nib に繋ぐ

ViewController

以下のようにViewControllerを記述します。 Bind する Model とその配列を ViewController に書きます。

class Item: NSObject{
    @objc dynamic var name: String? = ""
    @objc dynamic var image: NSImage? = nil
    init(name :String?, image: NSImage?){
        self.name = name
        self.image = image
    }
}

class ViewController: NSViewController {
    // Model配列
    @objc dynamic var items = [Item]()
    // ArrayController
    @IBOutlet var itemsArrayController: NSArrayController!
    // CollectionView
    @IBOutlet weak var collectionView: NSCollectionView!

    override func viewDidLoad() {
        super.viewDidLoad()
        // Contentを追加
        items.append(.init(name: "1", image: NSImage.init(named: NSImage.actionTemplateName)))
        items.append(.init(name: "2", image: NSImage.init(named: NSImage.addTemplateName)))
        items.append(.init(name: "3", image: NSImage.init(named: NSImage.advancedName)))

        // CollectionItemを登録する
        self.collectionView.register(NSNib.init(nibNamed: "CustomCollectionViewItem", bundle: nil), forItemWithIdentifier: NSUserInterfaceItemIdentifier.init("CustomCollectionViewItem") )

        // contentに設定する
        self.collectionView.content = items
    }
}

Bind を設定する

ArrayController

Content Array に ViewController に作成した Item 配列を指定します。

CollectionView

CollectionView->Content の Bind 先を ArrayController に設定します。 ※ControllerKey を arrangedObjects にします。

CollectionViewItem

各コントロールを選択し、Bind 先を CollectionViewItem に指定します。 ModelKeyPath を「representedObject.ItemClass のプロパティ」に設定

最後に

CollectionView のプロパティや、AutoLayout の設定をして完成。

完成

あとは items 配列をいじるだけで勝手に CollectionView に反映されます。

こちらにも同じ内容で記載しています。