swift - NSTextField 上的奇怪滚动

标签 swift cocoa nstextfield appkit

我有一个 NSTextField,每当它的内容发生变化时,我都会尝试根据特定条件自动调整大小。

有时,当开始输入内容时,文本字段的可见部分开始向上(或向下)移动,如下图所示:

gif

如果我在 NSTextField 中单击,内容会再次出现在正确的位置。

在 XCode 中启动可视化调试器,我看到当这种情况发生时,NSTextField 的私有(private) subview :_NSKeyboardFocusClipView 有一个 frame Y 坐标为负数。

我不确定是什么原因造成的。

这是我的 textField 调整大小行为:

import Cocoa

struct TextFieldResizingBehavior {
  let maxHeight: CGFloat = 100000.0
  let maxWidthPadding: CGFloat = 10
  let minWidth: CGFloat = 50
  let maxWidth: CGFloat = 250

  func resize(_ textField: NSTextField) {
    let originalFrame = textField.frame

    var textMaxWidth = textField.attributedStringValue.size().width
    textMaxWidth = textMaxWidth > maxWidth ? maxWidth : textMaxWidth
    textMaxWidth += maxWidthPadding

    var constraintBounds: NSRect = textField.frame
    constraintBounds.size.width = textMaxWidth
    constraintBounds.size.height = maxHeight

    var naturalSize = textField.cell!.cellSize(forBounds: constraintBounds)

    // ensure minimun size of text field
    naturalSize.width = naturalSize.width < minWidth ? minWidth : naturalSize.width

    if originalFrame.height != naturalSize.height {
      // correct the origin in order the textField to grow down.
      let yOffset: CGFloat = naturalSize.height - originalFrame.height
      let newOrigin = NSPoint(
        x: originalFrame.origin.x,
        y: originalFrame.origin.y - yOffset
      )
      textField.setFrameOrigin(newOrigin)
    }

    textField.setFrameSize(naturalSize)

    Swift.print(
      "\n\n>>>>>> text field resized " +
        "\nnaturalSize=\(naturalSize)" +
        "\noriginalFrame=\(originalFrame)-\(originalFrame.center)" +
        "\nnewFrame=\(textField.frame)-\(textField.frame.center)"
    )
  }
}

NSTextFieldDelegate 方法上调用:

extension CanvasViewController: NSTextFieldDelegate {
  override func controlTextDidChange(_ obj: Notification) {
    if let textField = obj.object as? NSTextField {
      textFieldResizingBehavior.resize(textField)
    }
  }

最后我的文本字段在 viewController 中声明如下:

lazy var textField: NSTextField = {
    let textField = NSTextField()
    textField.isHidden = true
    textField.isEditable = false
    textField.allowsEditingTextAttributes = true
    return textField
  }()

完整代码在:https://github.com/fespinoza/linked-ideas-osx

最佳答案

问题的一部分是您直接调用了 becomeFirstResponder 方法。你不应该这样做。

根据documentation :

Use the NSWindow makeFirstResponder(_:) method, not this method, to make an object the first responder. Never invoke this method directly.

此外,您真的需要文本字段能够水平和垂直增长吗?仅根据高度使其动态化显然会更加直接。

关于swift - NSTextField 上的奇怪滚动,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43902740/

相关文章:

swift - 在 Swift 3 中设置明天的时间

swift - 你如何显示 NSStatusBar 项目并隐藏停靠栏图标?

objective-c - 取消选择 NSTextField 中的文本

objective-c - 在标签上启用自动换行

objective-c - 单击编辑 NSTextField

swift - 如何使用字典中的所有数据填充 tableView?

ios - 向弓所面向的方向射箭

macos - 如何快速获取分辨率更改事件?

objective-c - 字符串中的 URL 给出 null

objective-c - 将 NSString 中的第一个数字转换为整数?