我觉得NSTokenField中的代币有太多的内边距,即我相信两个半圆(在每一边)应该更接近文本。默认设置浪费了太多空间。
如何减少这些边距,并使令牌更紧凑?
答案 0 :(得分:1)
使用Objective-C运行时,似乎有一种方法可以在不对子类进行子类化的情况下实现此目的。但是,这可能无法满足App Store的要求。
要使用Objective-C运行时,请添加
#import <objc/runtime.h>
到要对标记进行修改的文件的顶部。在此文件的类别或类别@implementation
中(可能是NSTokenField
或NSTokenFieldCell
上的类别),添加
static NSSize (*kOriginalCellSizeForBounds)(id, SEL, NSRect);
NSSize cellSizeForBounds_override(id self, SEL _cmd, NSRect rect)
{
NSSize size = kOriginalCellSizeForBounds(self, _cmd, rect);
size.width -= 10;
return size;
}
static NSRect (*kOriginalTitleRectForBounds)(id, SEL, NSRect);
NSRect titleRectForBounds_override(id self, SEL _cmd, NSRect rect)
{
NSRect titleRect = kOriginalTitleRectForBounds(self, _cmd, rect);
titleRect = NSInsetRect(rect, -5, 0);
return titleRect;
}
+ (void)load
{
Class tokenAttachmentCellClass = objc_getClass("NSTokenAttachmentCell");
SEL selector = @selector(cellSizeForBounds:);
Method originalMethod = class_getInstanceMethod(tokenAttachmentCellClass, selector);
kOriginalCellSizeForBounds = (void *)method_getImplementation(originalMethod);
if(!class_addMethod(tokenAttachmentCellClass, selector, (IMP)cellSizeForBounds_override, method_getTypeEncoding(originalMethod))) {
method_setImplementation(originalMethod, (IMP)cellSizeForBounds_override);
}
selector = @selector(titleRectForBounds:);
originalMethod = class_getInstanceMethod(tokenAttachmentCellClass, selector);
kOriginalTitleRectForBounds = (void *)method_getImplementation(originalMethod);
if(!class_addMethod(tokenAttachmentCellClass, selector, (IMP)titleRectForBounds_override, method_getTypeEncoding(originalMethod))) {
method_setImplementation(originalMethod, (IMP)titleRectForBounds_override);
}
}
这里发生的是我们减少令牌的原始宽度(在cellSizeForBounds_override()
中)并按比例增加单元格“标题”的宽度(在titleRectForBounds_override()
中)。结果是具有降低的水平边距的令牌仍可在NSTokenField
中正常工作。你可以修改宽度的减少量来获得你想要的效果。
您可以在Mike Ash的文章“Method Replacement for Fun and Profit”中阅读有关方法调配的更多信息;我正在使用“直接覆盖”方法调配。
答案 1 :(得分:0)
答案与此类似:How do I set the column margins in an NSTableView?
您需要子类化NSTextFieldCell并覆盖-titleRectForBounds:以传递矩形超级返回的宽度插入副本。
答案 2 :(得分:0)
我不得不对一个不属于公共API的类进行子类化。我通过BWToolkit中的BWTokenField代码了解了该怎么做。它可以工作,但我想在没有公共API的情况下这样做,因为有一天我可能想去Mac App Store。我已经提交了一份错误报告,要求公开API,他们将报告标记为重复。我并不乐观,他们会对此采取任何措施。