[AppKit] NSTokenField/NSTokenFieldDelegate

     
⌛️ 2 min.
NSTokenField と NSTokenFieldDelegate について UI操作でのやりとりをまとめます

環境&対象

以下の環境で動作確認を行なっています。

  • macOS14.1 Beta(23B5056e)
  • Xcode 15
  • Swift 5.9

NSTokenField, NSTokenFieldDelegate

NSTokenField は、以下のような UI をもつ AppKit が提供する Control の1つです。

TokenField

メールアプリの送信先アドレス指定のUIに同様の Control が使われている気がします。

複数項目の入力を受け付ける時に、個々の項目の区切りがわかりやすくなります。

SwiftUI の 部品は充実してきましたが、NSTokenField 相当の要素はまだ 提供されていないため、NSViewRepresentable での利用が必要な AppKit の部品の1つです。

一般的に AppKit では、Delegate を使って、制御するパターンが多く、NSTokenField も Delegate をうまく使うことが必要です。

NSTokenField では、入力された文字列により候補を表示することができるのですが、その候補表示あり/なし それぞれのケースで、 主要な Delegate method が呼び出されるタイミングを確認してみました。

補完なしのケース

以下は、補完候補の表示が行われないケースでの NSTokenField, NSTokenFieldDelegate でのやりとりです。

“return” を入力すると そこまでの入力を Token にしますが、”return” を入力するか NSTokenField がフォーカスを失うかで呼び出し順が少し変わります。

# 厳密には、そこまでに入力された値での Token 化を許諾するかどうかで変わりますが、以下では 入力されたものはすべて Token として受け取る設定でのやりとりです。

sequenceDiagram
	title NSTokeNField and NSTokenFieldDelegate (no completion)
	participant A as UI 
	participant B as NSTokenField
	participant C as NSTokenFieldDelegate
	loop
	A->>B: type key
		rect rgb(255,255,0,0.1)
		Note right of B:  only for first type
		%%opt only for first type
		B->>C: control(_:textShouldBeginEditing:)
		B->>C: controlTextDidBeginEditing(_:)
		end
      B->>C: controlTextDidChange(_:)
	%%B->>C: (tokenField(_:completionsForSubstring:indexOfToken:indexOfSelectedItem:))
	end
	alt tokenize then loose focus or just loose focus
	rect rgb(0,255,0,0.1)
      Note right of A: with tokenize
      A->>B: type "return" to make it token
	B->>C: tokenField(_:representedObjectForEditing:)
	B->>C: tokenField(_:shouldAdd:at:)
	B->>C: tokenField(_:displayStringForRepresentedObject:)
      B->>C: controlTextDidChange(_:)
	B->>B: loose focus
	B->>C: control(_:textShouldEndEditing:)
	B->>C: controlTextDidEndEditing(_:)
        end
        else
	rect rgb(0,255,255,0.1)
      Note right of A: loose focus without tokenize
	B->>B: loose focus
	B->>C: control(_:textShouldEndEditing:)
	B->>C: tokenField(_:representedObjectForEditing:)
	B->>C: controlTextDidEndEditing(_:)
	%%B->>C: tokenField(_:displayStringForRepresentedObject:)
      end
	end

補完ありのケース

補完ありのケースは、以下です。

候補から選択された時の呼び出し、候補表示をキャンセルされた(エスケープキーを押された)時の呼び出しが少し変わりますが、基本同じです。

sequenceDiagram
	title NSTokeNField and NSTokenFieldDelegate (with completion)
	participant A as UI 
	participant B as NSTokenField
	participant C as NSTokenFieldDelegate
	loop type something
      Note right of A: type somthing
	A->>B: type key
		rect rgb(255,255,0,0.1)
		opt only for first type
		B->>C: control(_:textShouldBeginEditing:)
		B->>C: controlTextDidBeginEditing(_:)
		end
		end
      B->>C: controlTextDidChange(_:)
	B->>C: tokenField(_:completionsForSubstring:indexOfToken:indexOfSelectedItem:)
      B->>C: (controlTextDidChange(_:))
	end

	alt 
	rect rgb(0,255,0,0.1)
      Note right of A: select one from completion
      A->>B: select one of completion
      B->>C: controlTextDidChange(_:)
	B->>C: tokenField(_:representedObjectForEditing:)
	B->>C: tokenField(_:shouldAdd:at:)
	B->>C: tokenField(_:displayStringForRepresentedObject:)
      B->>C: controlTextDidChange(_:)
        end
        else
	rect rgb(0,255,255,0.1)
      Note right of A: cancel (type escape)
      A->>B: type "escape"
      B->>C: controlTextDidChange(_:)
	end
	end

まとめ

NSTokenField/NSTokenFieldDelegate のやりとりを確認しました。

NSTokenField/NSTokenFieldDelegate のやりとり
  • NSTokenFieldDelegate の設定で補完候補表示ありなしが変わる
  • NSTokenFieldDelegate の実装で、token 化の振る舞いが変わる
  • TextField としての実装は、 (継承している) NSControlTextEditingDelegate/NSTextFieldDelegate が担当
  • 微妙な呼び出し順に気をつけることが必要なケースがありそう

説明は以上です。
不明な点やおかしな点ありましたら、こちらまで。

SwiftUI おすすめ本

SwiftUI を理解するには、以下の本がおすすめです。

SwiftUI ViewMatery

SwiftUI で開発していくときに、ViewやLayoutのための適切なmodifierを探すのが大変です。
英語での説明になってしまいますが、以下の”SwiftUI Views Mastery Bundle”という本がビジュアル的に確認して探せるので、便利です。

英語ではありますが、1ページに コードと画面が並んでいるので、非常にわかりやすいです。

View に適用できる modifier もわかりやすく説明されているので、ビューの理解だけではなく、どのような装飾ができるかも簡単にわかります。

超便利です

SwiftUIViewsMastery

販売元のページは、こちらです。

SwiftUI 徹底入門

# SwiftUI は、毎年大きく改善されていますので、少し古くなってしまいましたが、いまでも 定番本です。

Swift学習におすすめの本

詳解Swift

Swift の学習には、詳解 Swift という書籍が、おすすめです。

著者は、Swift の初期から書籍を出していますし、Swift の前に主力言語だった Objective-C という言語についても同様の書籍を出しています。

最新版を購入するのがおすすめです。

現時点では、上記の Swift 5 に対応した第5版が最新版です。

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です