На определенной высоте NSTextField макет будет таким, если размер текста мал
текст течет вверх, как сделать текстовый центр следующим образом:
На определенной высоте NSTextField макет будет таким, если размер текста мал
текст течет вверх, как сделать текстовый центр следующим образом:
Просто подкласс NSTextFieldCell
(или swizzle it)... и реализуйте...
- (NSRect) titleRectForBounds:(NSRect)frame {
CGFloat stringHeight = self.attributedStringValue.size.height;
NSRect titleRect = [super titleRectForBounds:frame];
titleRect.origin.y = frame.origin.y +
(frame.size.height - stringHeight) / 2.0;
return titleRect;
}
- (void) drawInteriorWithFrame:(NSRect)cFrame inView:(NSView*)cView {
[super drawInteriorWithFrame:[self titleRectForBounds:cFrame] inView:cView];
}
В основном я использую ответ Alex с одной поправкой: мы должны уменьшить высоту titleRect, если мы увеличим y-origin. В противном случае наш titleRect закончится под конец своего супервизора, возможно, скрывая любой контент ниже NSTextField.
.h:
#import <Cocoa/Cocoa.h>
@interface VerticallyCenteredTextFieldCell : NSTextFieldCell
@end
.m:
#import "VerticallyCenteredTextFieldCell.h"
@implementation VerticallyCenteredTextFieldCell
- (NSRect) titleRectForBounds:(NSRect)frame {
CGFloat stringHeight = self.attributedStringValue.size.height;
NSRect titleRect = [super titleRectForBounds:frame];
CGFloat oldOriginY = frame.origin.y;
titleRect.origin.y = frame.origin.y + (frame.size.height - stringHeight) / 2.0;
titleRect.size.height = titleRect.size.height - (titleRect.origin.y - oldOriginY);
return titleRect;
}
- (void) drawInteriorWithFrame:(NSRect)cFrame inView:(NSView*)cView {
[super drawInteriorWithFrame:[self titleRectForBounds:cFrame] inView:cView];
}
@end
Кроме того, VerticalCenteredTextFieldCell является подклассом NSTextFieldCell. Если вы подклассифицируете его, измените класс NSTextFieldCell в Interface Builder, а не на NSTextField (я этого не знал).
Добавив немного ответа Эрика и Хеязи, вам также нужно реализовать selectWithFrame
, вот решение в Swift 2.2:
class VerticallyCenteredTextFieldCell: NSTextFieldCell {
override func titleRectForBounds(rect: NSRect) -> NSRect {
var titleRect = super.titleRectForBounds(rect)
let minimumHeight = self.cellSizeForBounds(rect).height
titleRect.origin.y += (titleRect.height - minimumHeight) / 2
titleRect.size.height = minimumHeight
return titleRect
}
override func drawInteriorWithFrame(cellFrame: NSRect, inView controlView: NSView) {
super.drawInteriorWithFrame(titleRectForBounds(cellFrame), inView: controlView)
}
override func selectWithFrame(aRect: NSRect, inView controlView: NSView, editor textObj: NSText, delegate anObject: AnyObject?, start selStart: Int, length selLength: Int) {
super.selectWithFrame(titleRectForBounds(aRect), inView: controlView, editor: textObj, delegate: anObject, start: selStart, length: selLength);
}
}
class CustomTextFieldCell: NSTextFieldCell {
func adjustedFrame(toVerticallyCenterText rect: NSRect) -> NSRect {
// super would normally draw text at the top of the cell
var titleRect = super.titleRect(forBounds: rect)
let minimumHeight = self.cellSize(forBounds: rect).height
titleRect.origin.y += (titleRect.height - minimumHeight) / 2
titleRect.size.height = minimumHeight
return titleRect
}
override func edit(withFrame rect: NSRect, in controlView: NSView, editor textObj: NSText, delegate: Any?, event: NSEvent?) {
super.edit(withFrame: adjustedFrame(toVerticallyCenterText: rect), in: controlView, editor: textObj, delegate: delegate, event: event)
}
override func select(withFrame rect: NSRect, in controlView: NSView, editor textObj: NSText, delegate: Any?, start selStart: Int, length selLength: Int) {
super.select(withFrame: adjustedFrame(toVerticallyCenterText: rect), in: controlView, editor: textObj, delegate: delegate, start: selStart, length: selLength)
}
override func drawInterior(withFrame cellFrame: NSRect, in controlView: NSView) {
super.drawInterior(withFrame: adjustedFrame(toVerticallyCenterText: cellFrame), in: controlView)
}
override func draw(withFrame cellFrame: NSRect, in controlView: NSView) {
super.draw(withFrame: cellFrame, in: controlView)
}
}
Быстрая версия ответа Эрика Вегенера (также модифицированная для работы с несколькими строками):
class VerticallyCenteredTextFieldCell : NSTextFieldCell {
override func titleRect(forBounds rect: NSRect) -> NSRect {
var titleRect = super.titleRect(forBounds: rect)
let minimumHeight = self.cellSize(forBounds: rect).height
titleRect.origin.y += (titleRect.height - minimumHeight) / 2
titleRect.size.height = minimumHeight
return titleRect
}
override func drawInterior(withFrame cellFrame: NSRect, in controlView: NSView) {
super.drawInterior(withFrame: titleRect(forBounds: cellFrame), in: controlView)
}
}