Objective c 如何在NSTextField中垂直居中对齐文本?

Objective c 如何在NSTextField中垂直居中对齐文本?,objective-c,xcode,macos,Objective C,Xcode,Macos,我有一个NSTEXT字段,我想将其中的文本垂直居中对齐。基本上我需要的是 有人有什么建议吗?谢谢 您可以将NSTextFieldCell子类化以执行所需操作: MDVerticallyCenteredTextFieldCell.h: #import <Cocoa/Cocoa.h> @interface MDVerticallyCenteredTextFieldCell : NSTextFieldCell { } @end 然后,您可以在Interface Builder中使用

我有一个NSTEXT字段,我想将其中的文本垂直居中对齐。基本上我需要的是

有人有什么建议吗?谢谢

您可以将NSTextFieldCell子类化以执行所需操作:

MDVerticallyCenteredTextFieldCell.h:

#import <Cocoa/Cocoa.h>

@interface MDVerticallyCenteredTextFieldCell : NSTextFieldCell {

}

@end
然后,您可以在Interface Builder中使用常规的NSTextField,并指定MDVerticallyCenteredTextFieldCell或任何您想命名为文本字段的文本字段单元格的自定义类选择文本字段,暂停,然后再次单击文本字段以选择文本字段内的单元格:

在计算可能的最大字体高度时,最好使用boundingRectForFont和函数ceilf,因为上述解决方案会导致文本在基线下被截断。因此,AdjustedFrameToVerticallyCenter:将如下所示

- (NSRect)adjustedFrameToVerticallyCenterText:(NSRect)rect {
    CGFloat fontSize = self.font.boundingRectForFont.size.height;
    NSInteger offset = floor((NSHeight(rect) - ceilf(fontSize))/2);
    NSRect centeredRect = NSInsetRect(rect, 0, offset);
    return centeredRect;
}

Swift 3.0版本为NSTextFieldCell创建自定义子类:

override func drawingRect(forBounds rect: NSRect) -> NSRect {
    var newRect = super.drawingRect(forBounds: rect)
    let textSize = self.cellSize(forBounds: rect)
    let heightDelta = newRect.size.height - textSize.height
    if heightDelta > 0 {
        newRect.size.height -= heightDelta
        newRect.origin.y += (heightDelta / 2)
    }
    return newRect
}

这很好,只是它会导致文本溢出到左右两侧的textfield框架之外。有什么想法吗?@simon.d:对,你是。。。嗯,我一直在使用这段代码,我相信这段代码是从我在某处找到的一些苹果示例代码改编而来的,有一段时间没有出现任何问题,尽管我现在意识到它只使用单行非包装NSTEXT字段。我会再看一眼,看看它是否也适用于多行文本字段……也检查一下这个答案:@JFS这对我有用。但它不起作用
override func drawingRect(forBounds rect: NSRect) -> NSRect {
    var newRect = super.drawingRect(forBounds: rect)
    let textSize = self.cellSize(forBounds: rect)
    let heightDelta = newRect.size.height - textSize.height
    if heightDelta > 0 {
        newRect.size.height -= heightDelta
        newRect.origin.y += (heightDelta / 2)
    }
    return newRect
}