如何以编程方式绑定 NSCollectionView 的视图子类?

发布于 2024-07-29 10:34:09 字数 1593 浏览 11 评论 0原文

我已经成功创建了一个 NSCollectionView 并向 IB 中的视图原型添加了一个标签,绑定到我所表示的对象的属性。 我现在想以编程方式创建一个 NSButton 和 NSTextField,并将 NSTextField 绑定到我所表示的对象的属性。 单击按钮时我想显示和隐藏 NSTextField。

我遇到的问题是,如果我将控件的初始化代码放在视图的 initWithCoder 方法中,并将绑定放在视图的 awakeFromNib 中,则绑定不会连接起来。 如果我将控件的初始化放在 awakeFromNib 中,则单击按钮时,我无权访问视图中的控件(使用 NSLog 打印时它们为空)。

据我所知,问题可能在于 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

I've successfully created an NSCollectionView and added a label to the view prototype in IB, bound to a property of my represented object. I now want to programmatically create an NSButton and NSTextField with the NSTextField bound to a property of my represented object. When the button is clicked I want to show and hide the NSTextField.

The problem I've come across is if I put my initialization code for my controls in the view's initWithCoder method, and the binding in the view's awakeFromNib, the binding doesn't get hooked up. If I put the initialization for my controls in the awakeFromNib, when the button is clicked, I don't have access to the controls in my view (they are null when printed out using NSLog).

From what I can tell it looks like the issue may be that the way NSCollectionView works is, it creates an instance of the view, then copies it for how every many objects are in the collection view. How do I get the the buttons to initialize and the binding to work with the copy of the prototype?

Below is my initialization code and my binding in the awakeFromNib for my subclassed view:

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

南风几经秋 2024-08-05 10:34:09

这听起来与我刚刚所做的类似,所以也许这就是您所需要的。

子类 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

希望这离您需要的地方很近......

This sounds similar to something I just did, so maybe it's what you need.

Subclass NSCollectionView and override:

- (NSCollectionViewItem *)newItemForRepresentedObject:(id)object

In newItemForRepresentedObject:, retreive the view item, then add your controls and any programmatic bindings:

@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

Hopefully this is somewhere close to where you need to be...

最终幸福 2024-08-05 10:34:09

如果 NSCollectionViewItem 的视图与 NSCollectionView 位于同一笔尖中,则不会在该视图上调用 -awakeFromNib ,但如果将该视图放在单独的笔尖中,则会调用它。

  • 创建一个空 nib 文件 (BlahBlahCollectionViewItem.nib)。
  • 从您拥有的任何笔尖中剪切集合项视图 将
  • 其粘贴到新的笔尖文件中
  • 将其所有者的类更改为 NSCollectionViewItem。
  • 将所有者上的视图出口连接到新粘贴的视图
  • 打开包含 NSViewController 的 nib 文件
  • 选择关联的 NSViewControllerItem
  • 将其 Nib Name 属性更改为新 nib 的名称
  • 将代码保留在 -awakeFromNib

-awakeFromNib is not called on the view for a NSCollectionViewItem if that view is in the same nib as the NSCollectionView, but it is called if you put the view in a separate nib.

  • Create an empty nib file (BlahBlahCollectionViewItem.nib).
  • Cut the collection item view out of whatever nib you have it in
  • Paste it into the new nib file
  • Change the class of its owner to NSCollectionViewItem.
  • Connect the view outlet on the owner to the newly pasted view
  • Open the nib file containing the NSViewController
  • Select the associated NSViewControllerItem
  • Change its Nib Name property to the name of the new nib
  • Keep your code in -awakeFromNib
月光色 2024-08-05 10:34:09

从原型 NSCollectionViewItem 复制的视图不会调用 -awakeFromNib 。 将您的绑定代码放入 initWithCoder: 中,应该没问题。

-awakeFromNib is not called for views copied from the prototype NSCollectionViewItem. Put your binding code in initWithCoder: and you should be fine.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文