macOS App中

时间:2019-01-28 22:45:36

标签: autolayout nstableview nstextfield appkit

Xcode 10.1,Swift 4.2,macOS 10.14.2

我正在尝试为macOS制作一个简单的待办事项列表应用程序,其中有一系列NSTableView行,每行内部是NSTextField。每个字段都是一个待办事项。我希望NSTableView行能够扩展以适合每个NSTextField中文本的大小。

我有以下所有工作:

  1. NSTextField中设置文本可使NSTableView行根据需要扩展。在我的情节提要中设置了自动布局约束。
  2. 使用tableView.reloadData(forRowIndexes: ..., columnIndexes: ...)设置文本并正确调整表格行的大小。 reloadData works 但是执行tableView.reloadData()总是将每个NSTextField重置为一行文本,如下所示: reloadData fails 有趣的是,如果在重新加载整个表后单击NSTextField,则该字段将重新调整大小以适合其内容: Clicking a row fixes it

我相信我已经在NSTextField上设置了所有适当的自动布局约束,并且我也为此使用了自定义子类(来自helpful answer here):

class FancyField: NSTextField{
  override var intrinsicContentSize: NSSize {
    // Guard the cell exists and wraps
    guard let cell = self.cell, cell.wraps else {return super.intrinsicContentSize}

    // Use intrinsic width to jibe with autolayout
    let width = super.intrinsicContentSize.width

    // Set the frame height to a reasonable number
    self.frame.size.height = 150.0

    // Calcuate height
    let height = cell.cellSize(forBounds: self.frame).height

    return NSMakeSize(width, height)
  }

  override func textDidChange(_ notification: Notification) {
    super.textDidChange(notification)
    super.invalidateIntrinsicContentSize()
  }
}

⭐️这里是一个示例项目: https://d.pr/f/90CTEh

我无所适从。有什么想法吗?

1 个答案:

答案 0 :(得分:2)

我认为接口构建器中的约束存在一些基本问题。调整窗口的大小会使所有事情变幻莫测。另外,您还应该在validateEditing()类的textDidChange(forBounds:)中调用FancyField。 我创建了一个示例项目,该项目可以在Github

上满足您的需求

如果有任何疑问,请写评论。

对此稍加思考,以为我会在这里添加代码的内容。唯一真正需要工作的是更新“任务”时在NSTextField上进行的更新。以下是NSTextField所需的代码。

public class DynamicTextField: NSTextField {
   public override var intrinsicContentSize: NSSize {
      if cell!.wraps {
         let fictionalBounds = NSRect(x: bounds.minX, y: bounds.minY, width: bounds.width, height: CGFloat.greatestFiniteMagnitude)
         return cell!.cellSize(forBounds: fictionalBounds)
      } else {
         return super.intrinsicContentSize
      }
   }

   public override func textDidChange(_ notification: Notification) {
      super.textDidChange(notification)

      if cell!.wraps {
         validatingEditing()
         invalidateIntrinsicContentSize()
      }
   }
}

希望有帮助。