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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/8624834/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-14 22:49:32  来源:igfitidea点击:

How do I vertically center align text in a NSTextField?

objective-cxcodemacos

提问by simon.d

I have an NSTextField and I want to vertically center align the text in it. Basically I need the NSTextField answer of How do I vertically center UITextField Text?

我有一个 NSTextField,我想垂直居中对齐其中的文本。基本上我需要如何垂直居中 UITextField 文本的 NSTextField 答案

Anyone got some pointers? Thanks!

有人得到一些指点吗?谢谢!

回答by NSGod

You could subclass NSTextFieldCellto do what you want:

你可以子类化做NSTextFieldCell你想做的事:

MDVerticallyCenteredTextFieldCell.h:

MDVerticallyCenteredTextFieldCell.h:

#import <Cocoa/Cocoa.h>

@interface MDVerticallyCenteredTextFieldCell : NSTextFieldCell {

}

@end

MDVerticallyCenteredTextFieldCell.m:

MDVerticallyCenteredTextFieldCell.m:

#import "MDVerticallyCenteredTextFieldCell.h"

@implementation MDVerticallyCenteredTextFieldCell

- (NSRect)adjustedFrameToVerticallyCenterText:(NSRect)frame {
    // super would normally draw text at the top of the cell
    NSInteger offset = floor((NSHeight(frame) - 
           ([[self font] ascender] - [[self font] descender])) / 2);
    return NSInsetRect(frame, 0.0, offset);
}

- (void)editWithFrame:(NSRect)aRect inView:(NSView *)controlView
         editor:(NSText *)editor delegate:(id)delegate event:(NSEvent *)event {
    [super editWithFrame:[self adjustedFrameToVerticallyCenterText:aRect]
          inView:controlView editor:editor delegate:delegate event:event];
}

- (void)selectWithFrame:(NSRect)aRect inView:(NSView *)controlView
                 editor:(NSText *)editor delegate:(id)delegate 
                  start:(NSInteger)start length:(NSInteger)length {

    [super selectWithFrame:[self adjustedFrameToVerticallyCenterText:aRect]
                    inView:controlView editor:editor delegate:delegate
                     start:start length:length];
}

- (void)drawInteriorWithFrame:(NSRect)frame inView:(NSView *)view {
    [super drawInteriorWithFrame:
       [self adjustedFrameToVerticallyCenterText:frame] inView:view];
}

@end

You can then use a regular NSTextFieldin Interface Builder, and specify MDVerticallyCenteredTextFieldCell(or whatever you want to name it) as the custom class for the text field's text field cell (select the textfield, pause, then click the textfield again to select the cell inside the text field):

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

enter image description here

在此处输入图片说明

回答by Beninho85

Swift 3.0 version (Create a custom subclass for NSTextFieldCell):

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
}

回答by Vladislav Senyukov

It's better to use boundingRectForFontand the function ceilf()when calculating possible maximum font height, because the above-mentioned solution causes text to be cut off under the baseline. So the adjustedFrameToVerticallyCenterText:will look like this

最好在计算可能的最大字体高度时使用boundingRectForFont和 函数ceilf(),因为上述解决方案会导致文本在基线下被截断。所以adjustedFrameToVerticallyCenterText:看起来像这样

- (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;
}