为什么覆盖 `NSView` 中的 `intrinsicContentSize` 对 `NSScrollView` 不起作用?

Why doesn't overriding `intrinsicContentSize` in `NSView` work for `NSScrollView`?

我在 IB 的 NSScrollView 中放置了一个自定义 class BigView 的实例,它是 NSView 的子 class。我的 BigView 的内容大小将在运行时计算。设置内容大小的最佳做法是什么?

覆盖 intrinsicContentSize,如 The Big Nerd Ranch 指南中所建议的那样, 似乎有效——框架保持其原始大小:

class BigView: NSView {
   ...
   override var intrinsicContentSize: NSSize { // doesn't work?!
      return NSSize(width: 10000, height: 10000)
   }
   ...
 }

以编程方式(或在 IB 中)设置框架确实有效:

class BigView: NSView {
   ...
    override func awakeFromNib() {
       ...
       self.frame = NSRect(x: 0, y: 0, width: 10000, height: 10000)
    }
    ...
}I 

或来自控制器:

class ViewController: NSViewController {
   @IBOutlet weak var bigView: BigView!
   ...
   override func viewDidLoad() {
       super.viewDidLoad()
       bigView.frame = NSRect(x: 0, y: 0, width: 1000, height: 1000)
   }
   ...
}

这也可以在整个滚动视图中完成 documentView 属性:

class ViewController: NSViewController {
   @IBOutlet weak var scrollView: NSScrollView!
   ...
   override func viewDidLoad() {
       super.viewDidLoad()
       scrollView.documentView?.frame = NSRect(x: 0, y: 0, 
                                               width: 1000, height: 1000)
   }
   ...
}

我想也可以使用 AutoLayout 约束。

什么不覆盖 intrinsicContentSize 工作?

问题在于,当在较新版本的 AppKit 中启用 translatesAutoresizingMaskIntoConstraints 时,默认约束设置没有考虑固有大小。

要解决此问题,您需要手动添加约束。首先将 BigView 的位置固定到超级视图的左上角(应该是 NSClipView)。然后转到 Size Inspector,并在 Content Compression Resistance Priority 部分中将 Intrinsic Size 设置为 Placeholder .这为您的视图提供了它所需的约束,并且一切都应该在运行时运行。