是否有一个“正确”的方式有NSTextFieldCell绘制垂直居中文本?(Is there a “

2019-06-18 02:36发布

我有一个NSTableView多个文本列。 默认情况下, dataCell这些列是苹果的一个实例NSTextFieldCell类,它做各种各样奇妙的东西,但它绘制与细胞的顶部对齐文本,我希望文本在单元格中垂直居中。

有一个在一个内部标志NSTextFieldCell可用于垂直居中的文本,它精美的作品。 然而,因为它是一个内部标志,它的使用不被认可的苹果,它可以简单地消失无在未来的版本警告。 我目前正在使用这个内部标志,因为它是简单而有效的。 苹果显然已经花了一些时间来实现的功能,所以我不喜欢的重新实现它的想法。

所以; 我的问题是: 什么是执行一些行为完全像苹果的NStextFieldCell正确的方式,但平局垂直居中文本,而不是顶部对齐?

为了记录在案,这里是我当前的“解决方案”:

@interface NSTextFieldCell (MyCategories)
- (void)setVerticalCentering:(BOOL)centerVertical;
@end

@implementation NSTextFieldCell (MyCategories)
- (void)setVerticalCentering:(BOOL)centerVertical
{
    @try { _cFlags.vCentered = centerVertical ? 1 : 0; }
    @catch(...) { NSLog(@"*** unable to set vertical centering"); }
}
@end

使用方法如下:

[[myTableColumn dataCell] setVerticalCentering:YES];

Answer 1:

其他答案没有为多行工作。 因此,我开始继续使用无证cFlags.vCentered财产,但引起我的应用程序从App Store拒绝。 最后我用的马特·贝尔的解决方案,为多行,自动换行,和截短的最后一行的作品修改后的版本:

-(void)drawInteriorWithFrame:(NSRect)cellFrame inView:(NSView *)controlView {
    NSAttributedString *attrString = self.attributedStringValue;

    /* if your values can be attributed strings, make them white when selected */
    if (self.isHighlighted && self.backgroundStyle==NSBackgroundStyleDark) {
        NSMutableAttributedString *whiteString = attrString.mutableCopy;
        [whiteString addAttribute: NSForegroundColorAttributeName
                            value: [NSColor whiteColor]
                            range: NSMakeRange(0, whiteString.length) ];
        attrString = whiteString;
    }

    [attrString drawWithRect: [self titleRectForBounds:cellFrame] 
                     options: NSStringDrawingTruncatesLastVisibleLine | NSStringDrawingUsesLineFragmentOrigin];
}

- (NSRect)titleRectForBounds:(NSRect)theRect {
    /* get the standard text content rectangle */
    NSRect titleFrame = [super titleRectForBounds:theRect];

    /* find out how big the rendered text will be */
    NSAttributedString *attrString = self.attributedStringValue;
    NSRect textRect = [attrString boundingRectWithSize: titleFrame.size
                                               options: NSStringDrawingTruncatesLastVisibleLine | NSStringDrawingUsesLineFragmentOrigin ];

    /* If the height of the rendered text is less then the available height,
     * we modify the titleRect to center the text vertically */
    if (textRect.size.height < titleFrame.size.height) {
        titleFrame.origin.y = theRect.origin.y + (theRect.size.height - textRect.size.height) / 2.0;
        titleFrame.size.height = textRect.size.height;
    }
    return titleFrame;
}

(此代码假定ARC;添加一个自动释放attrString.mutableCopy后如果使用手工存储器管理)



Answer 2:

重写的NSCell的-titleRectForBounds:应该这样做-那就是负责告诉细胞在哪里画它的文本的方法是:

- (NSRect)titleRectForBounds:(NSRect)theRect {
    NSRect titleFrame = [super titleRectForBounds:theRect];
    NSSize titleSize = [[self attributedStringValue] size];
    titleFrame.origin.y = theRect.origin.y + (theRect.size.height - titleSize.height) / 2.0;
    return titleFrame;
}

- (void)drawInteriorWithFrame:(NSRect)cellFrame inView:(NSView *)controlView {
    NSRect titleRect = [self titleRectForBounds:cellFrame];
    [[self attributedStringValue] drawInRect:titleRect];
}


Answer 3:

FYI,这个效果很好,虽然我没有设法得到它留下来中心当您编辑单元格......我有时有大量文本的细胞并可能导致他们这个代码不重合,如果文本高度较大那么它的垂直试图小区中心它这里是我的修改方法:

- (NSRect)titleRectForBounds:(NSRect)theRect 
 {
    NSRect titleFrame = [super titleRectForBounds:theRect];
    NSSize titleSize = [[self attributedStringValue] size];
     // test to see if the text height is bigger then the cell, if it is,
     // don't try to center it or it will be pushed up out of the cell!
     if ( titleSize.height < theRect.size.height ) {
         titleFrame.origin.y = theRect.origin.y + (theRect.size.height - titleSize.height) / 2.0;
     }
    return titleFrame;
}


Answer 4:

对于任何试图利用这个球马特的drawInteriorWithFrame:inView:方法,这将不再绘制背景,如果你设置你的画之一。 为了解决这个附加的线沿线的东西

[[NSColor lightGrayColor] set];
NSRectFill(cellFrame);

您的开头drawInteriorWithFrame:inView:方法。



Answer 5:

虽然这是很老的问题...

我相信NSTableView的执行默认样式旨在严格遵守所有相同的大小和字体单行文字显示。

在这种情况下,我建议,

  1. 字体设置。
  2. 调整rowHeight

也许你会得到悄悄密行。 然后,通过设置给他们填充intercellSpacing

例如,

    core_table_view.rowHeight               =   [NSFont systemFontSizeForControlSize:(NSSmallControlSize)] + 4;
    core_table_view.intercellSpacing        =   CGSizeMake(10, 80);

在这里你会得到两个属性的调整。

这不会为多行文本工作,但也足够快垂直中心非常好,如果你不需要多行支持。



Answer 6:

我有同样的问题,这里是我做的解决方案:

1)在Interface Builder中,选择您的NSTableCellView。 确保它一样大的尺寸检查行高度。 例如,如果你的行高为32,让你的细胞高度32

2)确保您的电池处于有利位置你行(我的意思是可见的)

3)选择您的里面的TextField和去你的尺寸检查

4)你应该看到“安排”项,然后选择“垂直居中集装箱”

- > TextField的将中心本身在细胞



Answer 7:

号正确的做法是把场另外的看法,使用自动布局或父视图的布局定位。



文章来源: Is there a “right” way to have NSTextFieldCell draw vertically centered text?