e.J*_*mes 50 customization cocoa vertical-alignment nstextfieldcell
我有NSTableView几个文本列.默认情况下,dataCell这些列是Apple NSTextFieldCell类的一个实例,它可以执行各种奇妙的操作,但它会绘制与单元格顶部对齐的文本,并且我希望文本在单元格中垂直居中.
有一个内部标志NSTextFieldCell可以用来垂直居中文本,它工作得很漂亮.但是,由于它是一个内部标志,它的使用不受Apple的批准,它可能会在未来的版本中消失而不会发出警告.我目前正在使用这个内部标志,因为它简单而有效.Apple显然花了一些时间来实现这个功能,所以我不喜欢重新实现它的想法.
所以; 我的问题是:实现与Apple的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
Run Code Online (Sandbox Code Playgroud)
使用如下:
[[myTableColumn dataCell] setVerticalCentering:YES];
Run Code Online (Sandbox Code Playgroud)
Jak*_*ger 36
其他答案不适用于多行.因此,我最初继续使用未记录的cFlags.vCentered属性,但这导致我的应用程序被拒绝从应用程序商店.我最终使用了Matt Bell解决方案的修改版本,该解决方案适用于多行,自动换行和截断的最后一行:
-(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;
}
Run Code Online (Sandbox Code Playgroud)
(此代码假定ARC;如果使用手动内存管理,则在attrString.mutableCopy之后添加自动释放)
Mat*_*all 31
覆盖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];
}
Run Code Online (Sandbox Code Playgroud)
对于使用Matt Ball drawInteriorWithFrame:inView:方法尝试此操作的任何人,如果将单元格设置为绘制一个背景,则将不再绘制背景。为了解决这个问题,请添加以下内容:
[[NSColor lightGrayColor] set];
NSRectFill(cellFrame);
Run Code Online (Sandbox Code Playgroud)
到您的drawInteriorWithFrame:inView:方法开始。