有没有一个“正确的”? 让 NSTextFieldCell 绘制垂直居中文本的方法?
我有一个带有多个文本列的 NSTableView。 默认情况下,这些列的 dataCell 是 Apple 的 NSTextFieldCell 类的实例,该类可以执行各种奇妙的操作,但它会绘制与单元格顶部对齐的文本,我希望文本在单元格中垂直居中。
NSTextFieldCell
中有一个内部标志,可用于垂直居中文本,并且效果非常好。 然而,由于它是一个内部标志,因此它的使用不受苹果公司的批准,并且它可能会在未来的版本中毫无警告地消失。 我目前正在使用这个内部标志,因为它简单而有效。 苹果显然花了一些时间来实现该功能,所以我不喜欢重新实现它的想法。
所以; 我的问题是这样的: 实现与 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
使用方法如下:
[[myTableColumn dataCell] setVerticalCentering:YES];
I have an NSTableView
with several text columns. By default, the dataCell
for these columns is an instance of Apple's NSTextFieldCell
class, which does all kinds of wonderful things, but it draws text aligned with the top of the cell, and I want the text to be vertically centered in the cell.
There is an internal flag in NSTextFieldCell
that can be used to vertically center the text, and it works beautifully. However, since it is an internal flag, its use is not sanctioned by Apple and it could simply disappear without warning in a future release. I am currently using this internal flag because it is simple and effective. Apple has obviously spent some time implementing the feature, so I dislike the idea of re-implementing it.
So; my question is this: What is the right way to implement something that behaves exactly like Apple's NStextFieldCell, but draws vertically centered text instead of top-aligned?
For the record, here is my current "solution":
@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
Used as follows:
[[myTableColumn dataCell] setVerticalCentering:YES];
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(7)
其他答案不适用于多行。 因此,我最初继续使用未记录的
cFlags.vCentered
属性,但这导致我的应用程序被应用程序商店拒绝。 我最终使用了 Matt Bell 解决方案的修改版本,该解决方案适用于多行、自动换行和截断的最后一行:(此代码假定 ARC;如果您使用手动内存管理,请在 attrString.mutableCopy 之后添加自动释放)
The other answers didn't work for multiple lines. Therefore I initially continued using the undocumented
cFlags.vCentered
property, but that caused my app to be rejected from the app store. I ended up using a modified version of Matt Bell's solution that works for multiple lines, word wrapping, and a truncated last line:(This code assumes ARC; add an autorelease after attrString.mutableCopy if you use manual memory management)
虽然这是一个相当老的问题...
我相信 NSTableView 实现的默认样式严格用于具有相同大小和大小的单行文本显示。 字体。
在这种情况下,我建议
也许你会得到安静密集的行。 然后,通过设置 intercellSpacing 给它们填充。
例如,
以下是通过两个属性调整您将得到的结果。
这不适用于多行文本,但如果您不这样做,则对于快速垂直居中来说已经足够了不需要多线支持。
Though this is pretty old question...
I believe default style of NSTableView implementation is intended strictly for single line text display with all same size & font.
In that case, I recommend,
rowHeight
.Maybe you will get quietly dense rows. And then, give them padding by setting
intercellSpacing
.For example,
Here what you'll get with two property adjustment.
This won't work for multi-line text, but very good enough for quick vertical center if you don't need multi-line support.
重写 NSCell 的
-titleRectForBounds:
应该可以做到这一点——这是负责告诉单元格在哪里绘制文本的方法:Overriding NSCell's
-titleRectForBounds:
should do it -- that's the method responsible for telling the cell where to draw its text:对于任何使用 Matt Ball 的
drawInteriorWithFrame:inView:
方法尝试此操作的人来说,如果您已将单元格设置为绘制背景,则将不再绘制背景。 要解决此问题,请在drawInteriorWithFrame:inView:
方法的开头添加一些内容。For anyone attempting this using Matt Ball's
drawInteriorWithFrame:inView:
method, this will no longer draw a background if you have set your cell to draw one. To solve this add something along the lines ofto the beginning of your
drawInteriorWithFrame:inView:
method.仅供参考,这效果很好,尽管我在编辑单元格时未能使其保持居中...有时我的单元格包含大量文本,如果文本高度较大,此代码可能会导致它们未对齐然后是它试图将其垂直居中的单元格。这是我的修改方法:
FYI, this works well, although I haven't managed to get it to stay centered when you edit the cell... I sometimes have cells with large amounts of text and this code can result in them being misaligned if the text height is greater then the cell it's trying to vertically center it in. Here's my modified method:
不。正确的方法是将字段放在另一个视图中,并使用自动布局或父视图的布局来定位它。
No. The right way is to put the Field in another view and use auto layout or that parent view's layout to position it.
我遇到了同样的问题,这是我所做的解决方案:
1)在 Interface Builder 中,选择您的 NSTableCellView。 确保它与大小检查器中的行高一样大。 例如,如果您的行高为 32,则将单元格高度设置为 32
2) 确保您的单元格放置在行中(我的意思是可见)
3) 选择单元格内的 TextField 并转到尺寸检查器
4) 您应该查看“排列”项并选择“在容器中垂直居中”
--> TextField 将在单元格中居中
I had the same problem and here is the solution I did :
1) In Interface Builder, select your NSTableCellView. Make sure it as big as the row height in the Size Inspector. For example, if your row height is 32, make your Cell height 32
2) Make sure your cell is well placed in your row (I mean visible)
3) Select your TextField inside your Cell and go to your size inspector
4) You should see "Arrange" item and select "Center Vertically in Container"
--> The TextField will center itself in the cell