Vertically aligning text in an NSTextField using Swift

不打扰是莪最后的温柔 提交于 2019-12-21 03:57:26

问题


I have been reading through the various options on how to set the vertical alignment on an NSTextField. I want the text to be displayed in the center and to do it programatically in Swift. Here are the things I have looked so far:

  • http://www.cocoabuilder.com/archive/cocoa/174994-repositioning-an-nstextfieldcell.html
  • https://red-sweater.com/blog/148/what-a-difference-a-cell-makes
  • Vertically Centre Text in NSSecureTextField with subclassing
  • Get NSTextField contents to scale
  • vertically align text in a CATextLayer?

One thing I have tried in Swift is to set the following property:

textField.usesSingleLineMode = true

Any tips on the best way to vertically center text would be much appreciated!


回答1:


This is very hard to do, as Apple makes this very difficult. I achieved it by subclassing NSTextFieldCell and overriding the drawingRectForBounds: method like so:

override func drawingRectForBounds(theRect: NSRect) -> NSRect {
    let newRect = NSRect(x: 0, y: (theRect.size.height - 22) / 2, width: theRect.size.width, height: 22)
    return super.drawingRectForBounds(newRect)
}

This is just my way to do it, I'm sure there are better ways, which I don't know (yet). And this only works for the standard font size in TextFields (which gives a text height of 22). That's why I hardcoded that. Haven't figured out yet, how to get the height in the cell if you change the font.

Result:




回答2:


Try this on a playground, it centers the text perfectly, use it on your projects! Hope it helps!

import Cocoa

let cell = NSTableCellView()
cell.frame = NSRect(x: 0, y: 0, width: 100, height: 100)
let tf = NSTextField()
tf.frame = cell.frame
tf.stringValue = "MyTextfield"
tf.alignment = .Center

let stringHeight: CGFloat = tf.attributedStringValue.size().height
let frame = tf.frame
var titleRect:  NSRect = tf.cell!.titleRectForBounds(frame)

titleRect.size.height = stringHeight + ( stringHeight - (tf.font!.ascender + tf.font!.descender ) )
titleRect.origin.y = frame.size.height / 2  - tf.lastBaselineOffsetFromBottom - tf.font!.xHeight / 2
tf.frame = titleRect
cell.addSubview(tf)



回答3:


The accepted answer works perfectly and here's the Swift3 version.

class VerticallyAlignedTextFieldCell: NSTextFieldCell {
    override func drawingRect(forBounds rect: NSRect) -> NSRect {
        let newRect = NSRect(x: 0, y: (rect.size.height - 22) / 2, width: rect.size.width, height: 22)
        return super.drawingRect(forBounds: newRect)
    }
}



回答4:


I have added the NSTextField inside a NSView and centered it.

Another solution was (in an iOS project) to create a UILabel and allow it adjust its size (sizeToFit()) and again embed it inside a UIView.

I personally don't like the calculations in previous answers and the second solution for iOS works for all texts size and row numbers.




回答5:


I was also facing vertical alignment issue with NSTextField. My requirement involved, rendering a single-line string inside a NSTextField. Additionally, textfield needed to be resize implying we had programatically resized the font-point-size of the text inside text-field on resize. In this scenario we faced vertical-alignment issues - the mis-alignment was tough to grasp/understand in a straight forward way.

What finally worked:

So, in my scenario a simple, turn off the "Single Line Mode" in interface builder
for the text-field solved the issue.



来源:https://stackoverflow.com/questions/34379353/vertically-aligning-text-in-an-nstextfield-using-swift

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!