Is there a “right” way to have NSTextFieldCell draw vertically centered text?
我有一个带有多个文本列的
所以;我的问题是:实现与Apple的NStextFieldCell完全一样的行为,但绘制垂直居中的文本而不是顶部对齐的正确方法是什么?
记录下来,这是我当前的"解决方案":
1 2 3 4 5 6 7 8 9 10 11 | @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 |
用途如下:
1 | [[myTableColumn dataCell] setVerticalCentering:YES]; |
其他答案不适用于多行。因此,我最初继续使用未记录的
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 | -(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之后添加自动释放)。
重写NSCell的
1 2 3 4 5 6 7 8 9 10 11 | - (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]; } |
对于使用Matt Ball的
的行中添加一些内容
1 2 | [[NSColor lightGrayColor] set]; NSRectFill(cellFrame); |
到
仅供参考,这很好用,尽管在编辑单元格时我没有设法使它保持居中...有时我的单元格中包含大量文本,并且如果文本不正确,此代码可能会导致它们未对齐高度大于它试图垂直居中放置的单元格。这是我修改过的方法:
1 2 3 4 5 6 7 8 9 10 11 | - (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; } |
n
尽管这是一个很老的问题...
我相信NSTableView实现的默认样式严格用于具有相同大小的单行文本显示
n