Cocoa NSTokenField和删除令牌

Cocoa NSTokenField和删除令牌,cocoa,nstokenfield,Cocoa,Nstokenfield,我的应用程序允许用户将标签附加到某些模型对象(NSManagedObject的子类)。Tag类也是NSManagedObject的一个子类。我决定使用NSTokenField来显示标记,其中每个标记都包含一个标记实例作为表示对象。这一切都很好,但我陷入了这样的境地:用户删除了一个令牌,因为我想检查关联的标记是否已经过时,是否应该删除 我希望在NSTokenFieldDelegate或NSTokenFieldCellDelegate中有一个方法,该方法允许我拦截并检查令牌上的删除操作 通过谷歌搜索

我的应用程序允许用户将标签附加到某些模型对象(NSManagedObject的子类)。Tag类也是NSManagedObject的一个子类。我决定使用
NSTokenField
来显示标记,其中每个标记都包含一个标记实例作为表示对象。这一切都很好,但我陷入了这样的境地:用户删除了一个令牌,因为我想检查关联的标记是否已经过时,是否应该删除

我希望在
NSTokenFieldDelegate
NSTokenFieldCellDelegate
中有一个方法,该方法允许我拦截并检查令牌上的删除操作

通过谷歌搜索,我找到了解决这个问题的方法。我在我的控制器(令牌字段的委托)中实现了建议的方法
controlTextDidChange:
。检查作为参数传递的控件后,发现它是
NSTokenTextView
的一个实例,我找不到任何文档(可能是私有类)

是否有人遇到过这种情况,并找到了一种解决方案,在维护所表示对象的底层模型的同时优雅地删除令牌

编辑

我也发现了这一点,这似乎表明出于某种原因,它并不像我们其他人期望的那样工作。

我放弃了(在跌跌撞撞了6个多小时之后)使用NSTokenField就地编辑标记的方法。最终,我遇到了一些脆弱的黑客攻击,这些攻击会波及到我的应用程序,因为在不同的地方都需要这个功能

除非有人有一些强项来反驳我目前的观点,否则NSTokenField是一个丑陋的怪物,给党带来了一个半生不熟的实现。这是一个遗憾,因为它的演示方面真的吸引了我

编辑:经过一些进一步的试验,我决定了一个合理的可接受的折衷方案。我以只读模式使用NSTokenField。它从我的核心数据存储中获取相关标记,并将它们显示为令牌。我为每个令牌添加了一个菜单,允许用户编辑、删除或查看标记。令牌字段旁边的标准按钮允许添加新标签。使用NSPOVERS实现编辑和审阅。请参见此示例:

还有一些小问题:

  • 当鼠标悬停在令牌字段上时,令牌往往会在任意时间消失。这似乎是一个bug
  • 由于token字段只接受NSArray进行绑定,因此我引入了一个名为
    tagsasararay
    的“虚拟属性”,它接受关联的标记并将它们从NSSet转换为NSArray。我认为这会影响KVO,因为标记的编辑只有在按enter键或在令牌字段外单击后才会显示

您应该能够通过创建一个令牌包装类来模拟删除委托,该类具有指向所有者和包装对象的指针:

@protocol TokenWrapperDelegate 
-(void)tokenWasDeleted:(id)token;
@end

@interface TokenWrapper : NSObject {
  id<TokenWrapperDelegate> owner;
  id token;
}
-(id)initWithWrappedToken:(id)token owner:(id<TokenWrapperDelegate>)owner;
@property (nonatomic, weak) id<TokenWrapperDelegate> owner;
@property (nonatomic, strong) id token;
@end
然后在您的
representedObjectForEditingString
回调中,返回一个指向您的所有者和真实令牌的自动释放包装器。您还必须确保更改其他NSTokenField委托回调以深入研究包装器对象。 当您手动更改NSTokenField的内容时(如通过调用setObjectValue),请确保所有者设置了一点以忽略这些回调

@implementation TokenWrapper

...

-(void)dealloc {
  [owner tokenWasDeleted:self.token];
  self.token = nil;
  [super dealloc];
}

@end