Sponsor Link
環境&対象
- macOS14.1 Beta(23B5056e)
- Xcode 15
- Swift 5.9
NSTokenField, NSTokenFieldDelegate
NSTokenField は、以下のような UI をもつ AppKit が提供する Control の1つです。
メールアプリの送信先アドレス指定の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 のやりとりを確認しました。
- NSTokenFieldDelegate の設定で補完候補表示ありなしが変わる
- NSTokenFieldDelegate の実装で、token 化の振る舞いが変わる
- TextField としての実装は、 (継承している) NSControlTextEditingDelegate/NSTextFieldDelegate が担当
- 微妙な呼び出し順に気をつけることが必要なケースがありそう
説明は以上です。
不明な点やおかしな点ありましたら、こちらまで。
SwiftUI おすすめ本
SwiftUI を理解するには、以下の本がおすすめです。
SwiftUI ViewMatery
SwiftUI で開発していくときに、ViewやLayoutのための適切なmodifierを探すのが大変です。
英語での説明になってしまいますが、以下の”SwiftUI Views Mastery Bundle”という本がビジュアル的に確認して探せるので、便利です。
英語ではありますが、1ページに コードと画面が並んでいるので、非常にわかりやすいです。
View に適用できる modifier もわかりやすく説明されているので、ビューの理解だけではなく、どのような装飾ができるかも簡単にわかります。
超便利です
販売元のページは、こちらです。
SwiftUI 徹底入門
# SwiftUI は、毎年大きく改善されていますので、少し古くなってしまいましたが、いまでも 定番本です。
Swift学習におすすめの本
詳解Swift
Swift の学習には、詳解 Swift という書籍が、おすすめです。
著者は、Swift の初期から書籍を出していますし、Swift の前に主力言語だった Objective-C という言語についても同様の書籍を出しています。
最新版を購入するのがおすすめです。
現時点では、上記の Swift 5 に対応した第5版が最新版です。
Sponsor Link