问题
I am wondering if there’s a possibility to set a margin or padding for NSTextField
?
I achieved a more or less custom looking textField (the first one in this screenshot)...
... using this code:
myTextField.wantsLayer = true
myTextField.layer?.cornerRadius = 2.0
myTextField.layer?.borderWidth = 1.0
myTextField.layer?.borderColor = CGColor(red: 0.69, green: 0.69, blue: 0.69, alpha: 1.0)
However, it feels like I have to add some padding on the left side so that the numbers are not too close to the border. Is that even possible?
回答1:
I usually do this just by putting the textField in a container view. You can give the view any corner radius, border, etc you want, and then just constrain the textField to the inside with whatever padding you want. Just make sure you change the textField's border style to 'none' or you'll be able to see it inside your view.
There might be a way to change the content inset like you can with a button, but I've never been able to find it.
回答2:
There's no simple and obvious way to do this, but like many things in AppKit, it's not too hard once you figure out exactly what you need to subclass. I came across this example by Hem Dutt and in my testing on macOS 10.12 this approach seems to work well. In short, you just need to subclass NSTextFieldCell
and override a few methods to change the text frame. Here's a variation in Swift 3:
class CustomTextFieldCell: NSTextFieldCell {
private static let padding = CGSize(width: 4.0, height: 2.0)
override func cellSize(forBounds rect: NSRect) -> NSSize {
var size = super.cellSize(forBounds: rect)
size.height += (CustomTextFieldCell.padding.height * 2)
return size
}
override func titleRect(forBounds rect: NSRect) -> NSRect {
return rect.insetBy(dx: CustomTextFieldCell.padding.width, dy: CustomTextFieldCell.padding.height)
}
override func edit(withFrame rect: NSRect, in controlView: NSView, editor textObj: NSText, delegate: Any?, event: NSEvent?) {
let insetRect = rect.insetBy(dx: CustomTextFieldCell.padding.width, dy: CustomTextFieldCell.padding.height)
super.edit(withFrame: insetRect, 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) {
let insetRect = rect.insetBy(dx: CustomTextFieldCell.padding.width, dy: CustomTextFieldCell.padding.height)
super.select(withFrame: insetRect, in: controlView, editor: textObj, delegate: delegate, start: selStart, length: selLength)
}
override func drawInterior(withFrame cellFrame: NSRect, in controlView: NSView) {
let insetRect = cellFrame.insetBy(dx: CustomTextFieldCell.padding.width, dy: CustomTextFieldCell.padding.height)
super.drawInterior(withFrame: insetRect, in: controlView)
}
}
I made one notable change from the original—overriding cellSize(forBounds:)
to increase the minimum height of the cell. I'm using Auto Layout to size the cell automatically, so without that override, my text was getting clipped.
来源:https://stackoverflow.com/questions/39906160/nstextfield-margin-and-padding-swift