1

ユーザーが新しい管理対象オブジェクトを追加すると、テーブルに表示され、新しいエントリまでスクロールダウンし、新しいオブジェクトの名前(デフォルト値)が編集モードになります。

新しいオブジェクトの名前がデータストア内で一意であるかどうかを確認する必要があるため、これにフォーマッターを使用できません。これを検証するのに最適な瞬間は、ユーザーがを使用してエントリの名前の値をコミットしようとするときtextShouldEndEditing:です。

次のメソッドをサブクラス化NSTableViewしてオーバーライドし、呼び出された場合にログをチェックできるようにしました。

- (BOOL)textShouldEndEditing:(NSText *)textObject {
    NSLog(@"textSHOULDendEditing fired in MyTableView");
    return [super textShouldEndEditing:textObject];
}
- (BOOL)control:(NSControl *)control textShouldEndEditing:(NSText *)fieldEditor {
    NSLog(@"control:textShouldEndEditing fired in MyTableView");
    return YES;
}
- (void)textDidEndEditing:(NSNotification *)aNotification {
    NSLog(@"textDIDEndEditing fired in MyTableView");
}

textDidEndEditing:うまく呼ばれますが、そうでtextShouldEndEditing:はありません。

NSTableViewクラスリファレンスの[テキストデリゲートメソッド]の下に、両方のメソッドtextShouldEndEditing:textDidEndEditing:が一覧表示されます。誰かが、なぜ一方が呼び出され、もう一方が呼び出されないのかを説明してください。


のブラックボックスデリゲートとしてインスタンス化されるNSTableViewのデリゲートとして機能すると思います。したがって、 NSTableViewクラスリファレンスでデリゲートメソッドと呼ばれるものは、実際にはオブジェクトのテキスト操作メソッドを実装します。NSTextFieldNSTextFieldCellNSTextField

NSTextFieldCell私は自分のでアウトレットとして宣言しようとしましたNSTableView。また、でいくつかのプロトコルを宣言しようとしましたNSTableView

#import <AppKit/AppKit.h>
#import <Cocoa/Cocoa.h>
@interface MyTableView : NSTableView <NSTextDelegate, NSTextFieldDelegate, NSControlTextEditingDelegate, NSTableViewDelegate, NSTableViewDataSource> {
}
@end

笑わないでください、私は自分のテーブルビューをそれ自身のデリゲートとして宣言しようとさえしました:P

4

3 に答える 3

7

Apple のドキュメントで決定的な答えを見つけることなく、この問題について 1 日頭を悩ませた後、他の誰かが同じ問題に苦しんでいる場合に備えて、私が見つけた解決策を共有することにしました。

ドキュメントによると、元の投稿者が述べたように、メソッドcontrol:textShouldBeginEditingcontrol:textShouldEndEditingofはデリゲートで直接NSControlTextEditingDelegate呼び出す必要があります。

このメッセージは、コントロールによってデリゲート オブジェクトに直接送信されます。

さらに、テクニカル Q&A が Apple によって発行され、NSTableViewでセルの編集セッションの開始と終了を検出するというタイトルで、次のことが明確に述べられています。

A: NSTableView でセルの編集セッションの開始と終了を検出するにはどうすればよいですか?

ユーザーが でセルの編集セッションを開始および終了しようとしていることを検出するにはNSTableView、そのテーブルのデリゲートとして設定し、次のNSControlデリゲート メソッドを実装する必要があります。

- (BOOL)control:(NSControl *)control textShouldBeginEditing:(NSText *)fieldEditor;

- (BOOL)control:(NSControl *)control textShouldEndEditing:(NSText *)fieldEditor;

テーブルは、メソッドを使用して、テキスト ビューから取得したデリゲート メッセージをデリゲート オブジェクトに転送しますcontrol:textShouldEndEditing:。このようにして、テキスト ビュー フィールド エディターが代理として動作しているコントロールをデリゲートに通知できます。

Apple のドキュメントには、何か違うことを述べているものは何も見つかりませんでした。

実際、セルベースが使用されている場合、これは真実のようです。NSTableViewただし、テーブルをビューベースのテーブルに変更するとすぐに、テーブル デリゲート オブジェクトでデリゲート メソッドが呼び出されなくなります。

解決策

ただし、私が実行したいくつかのヒューリスティック テストでは、これらのデリゲート メソッドが次の場合にビューベース テーブルのデリゲートで呼び出されることが示されました。

  • テーブル デリゲートが設定されます。
  • 編集可能なコントロールのデリゲートが設定されます。

いずれかのデリゲートを削除すると、NSControlTextEditingDelegateプロトコルのメソッドは呼び出されません。

(唯一の)ドキュメントによると、予期しないことは、編集可能なコントロールのデリゲートを設定することです。一方、デリゲート通知を受け取るようにデリゲート オブジェクトを設定することは、私にとってかなり直感的に聞こえるので、最初に試したのはそのためです。しかし、落とし穴があります。しかし興味深いのは、それだけでは十分ではないということです。テーブル デリゲートが削除さNSControlTextEditingDelegateれると、編集可能なコントロールのデリゲートが設定されていても、メソッドは呼び出されません (これは私にとって最も奇妙なことです)。

これが他の誰かがこの問題で時間を無駄にしないのに役立つことを願っています.

于 2014-06-16T11:30:05.873 に答える
2

あなたの質問では、「管理対象オブジェクト」の挿入について言及していますが、それが問題でした。ビュー ベースのテーブルを使用しているようですが、textShouldEndEditing: メソッドはセル ベースのテーブルに対してのみ呼び出されます。

于 2012-07-18T10:03:17.980 に答える
1

(サブクラス化された) 管理対象オブジェクトをオーバーライド-(void)awakeFromInsert;して、name-property の一意の既定値を作成します。

-(BOOL)textShouldEndEditing:また、テーブルビューでメソッドをオーバーライドしませんでした。代わりに、新しく入力された name-property が (サブクラス化された) 管理対象オブジェクトの .xml ファイル内で一意であるかどうかを確認します-(BOOL)validate<Key>:error:

上記の 2 つの戦略を組み合わせると、すべての管理対象オブジェクトで一意の名前プロパティが生成されます。

NSTextFieldCell強制的に編集モードにし-(BOOL)textShouldEndEditing:て、毎回呼び出されたのかもしれません。


ただし、いくつかの発言:

-(BOOL)textShouldEndEditing:がNOを返すとNOを返すよう-(BOOL)validate<Key>:error:です。

-(BOOL)textShouldEndEditing:-(BOOL)validate<Key>:error:メソッドの両方が呼び出されるのは、ユーザーが実際にプロパティを変更した場合のみです。

于 2012-04-16T15:17:34.890 に答える