【问题标题】:NSTokenField and deleting tokensNSTokenField 和删除令牌
【发布时间】:2011-12-23 16:28:13
【问题描述】:

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

我期待 NSTokenFieldDelegateNSTokenFieldCellDelegate 中的一个方法,它可以让我拦截并检查令牌上的删除操作。

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

有没有人遇到过这个问题并找到了一个解决方案,可以在保持表示对象的底层模型的同时优雅地删除标记?

编辑

我也找到了this,这似乎表明出于某种原因,它的设计并不像我们其他人所期望的那样工作。

【问题讨论】:

    标签: cocoa nstokenfield


    【解决方案1】:

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

    @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)时,请确保所有者设置一些忽略这些回调。

    【讨论】:

      【解决方案2】:

      我放弃了使用 NSTokenField 就地编辑我的标签的方法(在跌跌撞撞了 6 个多小时之后)。我最终得到了一些脆弱的 hack,它们会波及我的应用程序,因为很多地方都需要这个功能。

      除非有人有一些强项来反驳我目前的观点,否则 NSTokenField 有点丑陋,给聚会带来了半生不熟的实现。真可惜,因为它的展示方面真的很吸引我......

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

      还有一些小问题:

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2013-07-13
        • 1970-01-01
        • 1970-01-01
        • 2020-05-19
        • 1970-01-01
        • 1970-01-01
        • 2013-04-12
        相关资源
        最近更新 更多