在NSTableView行中垂直对齐文本

时间:2010-01-20 16:42:09

标签: cocoa nstableview nstableviewcell

我对NSTableView有一个小问题。当我在表格中增加行的高度时,其中的文本在行的顶部对齐,但我想将其垂直居中对齐!

任何人都可以建议我这样做吗?

谢谢,

Miraaj

5 个答案:

答案 0 :(得分:21)

这是一个简单的代码解决方案,它显示了一个可用于对齐TextFieldCell的子类。

标题

#import <Cocoa/Cocoa.h>


@interface MiddleAlignedTextFieldCell : NSTextFieldCell {

}

@end

代码

@implementation MiddleAlignedTextFieldCell

- (NSRect)titleRectForBounds:(NSRect)theRect {
    NSRect titleFrame = [super titleRectForBounds:theRect];
    NSSize titleSize = [[self attributedStringValue] size];
    titleFrame.origin.y = theRect.origin.y - .5 + (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];
}

@end

This blog entry显示了另一种效果也很好的解决方案。

答案 1 :(得分:8)

以上是上面答案的代码的Swift版本:

import Foundation
import Cocoa

class VerticallyCenteredTextField : NSTextFieldCell
{

    override func titleRectForBounds(theRect: NSRect) -> NSRect
    {
        var titleFrame = super.titleRectForBounds(theRect)
        var titleSize = self.attributedStringValue.size
        titleFrame.origin.y = theRect.origin.y - 1.0 + (theRect.size.height - titleSize.height) / 2.0
        return titleFrame
    }

    override func drawInteriorWithFrame(cellFrame: NSRect, inView controlView: NSView)
    {
        var titleRect = self.titleRectForBounds(cellFrame)

        self.attributedStringValue.drawInRect(titleRect)
    }
}

然后我在NSTableView中设置tableView heightOfRow的高度:

func tableView(tableView: NSTableView, heightOfRow row: Int) -> CGFloat
{
    return 30
}

将NSTextFieldCell的类设置为VerticallyCenteredTextField:

enter image description here

和TableViewCell的高度

enter image description here

enter image description here

感谢Bryan的帮助。

答案 2 :(得分:0)

@ iphaaw为Swift 4更新了答案(注意我还在类名末尾添加了“Cell”,为了清晰起见,它还需要与Interface Builder中的类名相匹配):

import Foundation
import Cocoa

class VerticallyCenteredTextFieldCell : NSTextFieldCell {
    override func titleRect(forBounds theRect: NSRect) -> NSRect {
        var titleFrame = super.titleRect(forBounds: theRect)
        let titleSize = self.attributedStringValue.size
        titleFrame.origin.y = theRect.origin.y - 1.0 + (theRect.size.height - titleSize().height) / 2.0
        return titleFrame
    }

    override func drawInterior(withFrame cellFrame: NSRect, in controlView: NSView) {
        let titleRect = self.titleRect(forBounds: cellFrame)
        self.attributedStringValue.draw(in: titleRect)
    }
}

答案 3 :(得分:0)

即使这是一个非常老的问题,并且得到了公认的答案,这还是一个替代解决方案:

进入IB,选择位于NSTableCellView中的NSTextField并添加一个新的“在容器中垂直居中”约束。您还应该添加水平约束(可能会将前导/后继空间设置为0或任何适合您的需求)。

在NSOutlineView中使用了它,就像一个饰物一样工作。对于我而言,性能并不是问题,因为我没有太多的单元格,但是我希望它并不比手动计算尺寸差。

答案 4 :(得分:0)

对于某些属性字符串(例如带有上标),仅绘制属性字符串可能会产生奇怪的结果。

我建议在 drawInterior 中调用 super ......

  override func drawInterior(withFrame cellFrame: NSRect, in controlView: NSView) {
    super.drawInterior(withFrame: self.titleRect(forBounds: cellFrame), in: controlView)
}
相关问题