NSCollectionViewのビューサブクラスでプログラムでバインドするにはどうすればよいですか?
-
06-07-2019 - |
質問
NSCollectionViewを正常に作成し、IBのビュープロトタイプにラベルを追加しました。これは、表示されるオブジェクトのプロパティにバインドされています。 NSTextFieldを、表現されたオブジェクトのプロパティにバインドして、プログラムでNSButtonとNSTextFieldを作成します。ボタンがクリックされたとき、NSTextFieldを表示および非表示にします。
私が遭遇した問題は、コントロールの初期化コードをビューのinitWithCoderメソッドに入れ、ビューのawakeFromNibのバインディングを入れた場合、バインディングがフックされないことです。コントロールの初期化をawakeFromNibに配置すると、ボタンがクリックされたときに、ビュー内のコントロールにアクセスできません(NSLogを使用して印刷すると、nullになります)。
私が知ることができるのは、NSCollectionViewの動作方法がビューのインスタンスを作成し、それからコレクションビューにあるすべてのオブジェクトの数に応じてコピーすることである可能性があります。初期化するボタンとプロトタイプのコピーで動作するバインディングを取得するにはどうすればよいですか?
サブクラス化されたビューの初期化コードとawakeFromNibのバインディングは次のとおりです。
SubView.h
@interface SubView : NSView {
NSButton *button;
NSTextField *textField;
IBOutlet NSCollectionViewItem *item; // Connected in IB to my NSCollectionViewItem
}
- (IBAction)buttonClicked:(id)sender;
@end
SubView.m
@implementation SubView
- (id)initWithCoder:(NSCoder *)decoder
{
id view = [super initWithCoder:decoder];
button = [[NSButton alloc] initWithFrame:NSMakeRect(50, 95, 100, 20)];
[button setTitle:@"Begin Editing"];
[button setTarget:self];
[button setAction:@selector(buttonClicked:)];
[self addSubview:button];
textField = [[NSTextField alloc] initWithFrame:NSMakeRect(10, 10, 100, 75)];
[self addSubview:textField];
return(view);
}
- (void)awakeFromNib
{
// Bind the textField to the representedObject's name property
[textField bind:@"value"
toObject:item
withKeyPath:@"representedObject.name"
options:nil];
}
- (IBAction)buttonClicked:(id)sender
{
[button setTitle:@"End Editing"];
[textField setHidden:YES];
}
@end
解決
これは私がやったことと似ているように聞こえるので、おそらくあなたが必要としているものです。
サブクラス NSCollectionView およびオーバーライド:
- (NSCollectionViewItem *)newItemForRepresentedObject:(id)object
newItemForRepresentedObject:
で、ビューアイテムを取得し、コントロールとプログラムバインディングを追加します。
@implementation NSCollectionViewSubclass
- (NSCollectionViewItem *)newItemForRepresentedObject:(id)object {
// Allow the superclass to create or copy the collection view item
NSSCollectionViewItem *newItem = [super newItemForRepresentedObject:object];
// Get the new item's view so you can mess with it
NSView *itemView = [newItem view];
//
// add your controls to the view here, bind, etc
//
return newItem;
}
@end
うまくいけば、これはあなたがいる必要がある場所に近いところです...
他のヒント
-awakeFromNib
は呼び出されませんが、ビューを別のnibに入れると呼び出されます。
- 空のnibファイル(BlahBlahCollectionViewItem.nib)を作成します。
- 持っているペン先からコレクションアイテムビューを切り取ります
- 新しいnibファイルに貼り付けます
- 所有者のクラスをNSCollectionViewItemに変更します。
- 所有者のビューアウトレットを新しく貼り付けられたビューに接続します
- NSViewControllerを含むnibファイルを開きます
- 関連するNSViewControllerItemを選択
- 「ペン先名」プロパティを新しいペン先の名前に変更します
- コードを
-awakeFromNib
に保存します
-awakeFromNib
は、プロトタイプNSCollectionViewItemからコピーされたビューでは呼び出されません。バインディングコードを initWithCoder:
に入れると、問題ありません。