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

时间:2022-09-07 10:45:23

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,我想垂直居中对齐文本。基本上我需要NSTextField答案如何垂直居中UITextField文本?

Anyone got some pointers? Thanks!

有人有指点吗?谢谢!

3 个解决方案

#1


18  

You could subclass NSTextFieldCell to 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 NSTextField in 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):

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

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

#2


2  

It's better to use boundingRectForFont and 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(),因为上述解决方案会导致文本在基线下被切断。所以adjustFrameToVerticallyCenterText:将如下所示

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

#3


2  

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
}

#1


18  

You could subclass NSTextFieldCell to 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 NSTextField in 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):

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

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

#2


2  

It's better to use boundingRectForFont and 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(),因为上述解决方案会导致文本在基线下被切断。所以adjustFrameToVerticallyCenterText:将如下所示

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

#3


2  

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
}