この 記事 では、いろんなところでドラッグ&ドロップ操作ができるようにした、ということを書いていますが、いちばん対応に苦労したのが、NSTextView へのドロップ でした。
NSTextView のサブクラスで、独自形式の項目のドロップを受け付ける、あるいは、ドロップされた項目の処理を、独自に実装するには
障害になるのは、ドラッグ&ドロップを実装すること自体がちょっとややこしいことと、NSTextView が、標準でテキストやファイルのドロップに対応しているため、独自形式の項目をドロップできるようにするには、標準の実装を殺さないように、うまく立ち回らなくてはならないことです。
これにはみんな苦労しているようで、cocoa-dev ML には、やたらとこのテーマの質問が投稿されていますが、その中で本当に役に立った記事を紹介しておきます:
この記事では、必要な (標準で対応している項目の処理方法を変えるのが目的のコードだからか。) ドロップされた項目を、標準の実装に任せるのか、自分で処理するのか判定する部分の効率が悪いこと、registerForDraggedTypes:
をしていないこと、-performDragOperation:
の部分で、呼び出すスーパークラスのメソッドが間違っている、など注意しなければならない点がありますが、基本的には、これに習えばちゃんと動くはずです。(まあ、その前にちゃんと動かなかったのは、書き方が適当すぎたからですが 汗)
カーソルの位置を、マウスポインタの位置に追従させるには
テキストエディタで文字列をドラッグしてみると分かりますが、標準では、NSTextView 内のカーソルの位置が、マウスポインタの位置に追従します。しかし、ドラッグされている項目の処理を自分で受け取ると、これが動作しないようです。
この場合、自分でカーソルの位置を再計算する必要がありますが、以下の記事に、そのためのコードが掲載されています:
あとは -draggingUpdated:
の中などで、自分(NSTextView)に setSelectedRange:
してやれば OK です。ただし、別のウィンドウなどからドラッグしてきた項目の場合は、まだカーソルの位置が見えないので、-draggingEntered:
の中などで、自分を firstResponder にしてもらえばいいでしょう。