我的应用程序允许用户将标签附加到某些模型对象(NSManagedObject的子类)。 Tag类也是NSManagedObject的子类。我决定使用NSTokenField
来显示标记,其中每个标记都包含Tag的实例作为表示的对象。这一切都很好,但我遇到了用户删除令牌的情况,因为我想检查相关的标签是否已经过时,应该被删除。
我期待NSTokenFieldDelegate
或NSTokenFieldCellDelegate
中的方法允许我拦截并检查令牌上的删除操作。
经过一些谷歌搜索后,我发现this post解决了这个话题。我在我的控制器中实现了建议的方法controlTextDidChange:
(令牌字段的委托)。在检查作为参数传递的控件时,它显示为NSTokenTextView
的一个实例,我找不到任何文档(可能是私有类)。
有没有人碰到这个并找到一个解决方案来优雅地删除令牌,同时维护表示对象的基础模型?
修改
我也发现了this,这似乎表明,由于某种原因,它并不像我们其他人所期望的那样工作。
答案 0 :(得分:3)
在使用NSTokenField编辑我的标签的过程中,我放弃了(在绊倒了6个多小时之后)。我最终得到了一些脆弱的黑客攻击,这些黑客攻击会影响我的应用程序,因为在不同的地方需要这个功能。
除非有人强烈反对我目前的观点,否则NSTokenField是一个丑陋的怪物,为派对带来了一半的实施。这是一种耻辱,因为它的呈现方面真的很吸引我......
编辑:经过一些进一步的实验,我找到了一个合理可接受的妥协。我以只读模式使用NSTokenField。它从我的Core Data商店获取相关标签并将其显示为令牌。我为每个令牌添加了一个菜单,允许用户编辑,删除或查看标签。令牌字段旁边的标准按钮允许添加新标签。使用NSPopovers实现编辑和审阅。见这个例子:
仍有一些小问题:
tagsAsArray
的“虚拟属性”,它接受相关标记并将它们从NSSet转换为NSArray。我认为这会影响KVO,因为标签的编辑仅在按下输入或在令牌字段外单击后才会显示。答案 1 :(得分:3)
您应该能够通过创建一个令牌包装类来模拟删除委托,该类具有指向所有者以及包装对象的指针:
@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
然后让TokenWrapper dealloc通知所有者该令牌已被删除:
@implementation TokenWrapper
...
-(void)dealloc {
[owner tokenWasDeleted:self.token];
self.token = nil;
[super dealloc];
}
@end
然后在representedObjectForEditingString
回调中,返回指向您的所有者和真实令牌的自动释放包装器。您还必须确保更改其他NSTokenField委托回调以深入研究包装器对象。
当您手动更改NSTokenField的内容时(例如通过调用setObjectValue),确保所有者设置了一些忽略这些回调的信息。