【问题标题】:NSTextField margin and padding? (Swift)NSTextField 边距和填充? (迅速)
【发布时间】:2016-10-06 21:51:14
【问题描述】:

我想知道是否可以为NSTextField 设置边距或填充?

我实现了一个或多或少具有自定义外观的 textField(此屏幕截图中的第一个)...

...使用此代码:

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)

但是,感觉我必须在左侧添加一些填充,以便数字不会太靠近边框。这可能吗?

【问题讨论】:

  • 为什么不居中对齐?

标签: swift xcode swift3 padding nstextfield


【解决方案1】:

没有简单而明显的方法可以做到这一点,但就像 AppKit 中的许多事情一样,一旦你弄清楚你需要子类化什么就不会太难了。我遇到了this example by Hem Dutt,在我对 macOS 10.12 的测试中,这种方法似乎效果很好。简而言之,您只需要继承NSTextFieldCell 并重写一些方法来更改文本框架。这是 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)
    }

}

我对原始版本进行了一项显着更改——覆盖 cellSize(forBounds:) 以增加单元格的最小高度。我正在使用自动布局来自动调整单元格的大小,所以如果没有覆盖,我的文本就会被剪裁。

【讨论】:

  • 将单元格添加到文本字段的实现是什么?
  • @Sentry.co 子类NSTextField,覆盖cellClass,并在那里返回您的自定义单元类。
  • 我们正在这样做,但我看到重写的编辑函数永远不会被调用(至少在 MacOS 12.2 中),所以如果你输入多行然后删除,文本插入会变得混乱一些文字。
【解决方案2】:

我通常只需将 textField 放在容器视图中即可。您可以为视图提供您想要的任何角半径、边框等,然后使用您想要的任何填充将 textField 约束到内部。只需确保将 textField 的边框样式更改为“无”,否则您将能够在视图中看到它。

可能有一种方法可以像使用按钮一样更改内容插入,但我一直找不到。

【讨论】:

  • 这个解决方案的问题是如果选择了textField,高亮的边框与容器视图的边框不匹配
  • 是的,你是对的。你最终只需要选择对你来说更重要的东西,因为填充的东西似乎没有以干净的方式得到支持。
猜你喜欢
  • 1970-01-01
  • 2011-04-17
  • 2013-05-15
  • 2023-04-02
  • 1970-01-01
  • 2015-04-12
  • 1970-01-01
  • 2012-04-02
  • 2012-07-27
相关资源
最近更新 更多