将Center.app中的NSScrollView文档视图居中?

时间:2013-12-24 14:23:58

标签: macos cocoa autolayout

我问的问题与Trouble with autolayout on NSScrollView's document view几乎完全相同。此问题的解决方案是在translatesAutoresizingMaskIntoConstraints中将NO设置为-awakeFromNib:

然而,对我来说(我正在使用Xcode 5),这个标志在加载nib时已经设置为NO,所以我似乎遇到了另一个问题。

我想用图像缩放复制Preview.app细节的方式,只使用布局约束(如果可能)。当图像大小小于内容视图边界时,将显示完整图像。但是,当图像缩放时,滚动条会激活以允许导航。这看起来很简单。下面是我构建的视图层次结构。请注意,图像视图包含在自定义NSView中(这是因为我一直在遵循上一个自定义视图绘制背景的问题方法),此容器视图是NSScrollView的documentView而不是嵌入的视图使用IB的嵌入命令在滚动视图中。

Zooming an image in a scroll view.

我在IB中设置了以下约束:

  • 图像视图的intrinsicContentSize设置为图像的大小。在IB中,占位符大小用于使约束满意。
  • 图像包含视图被限制为具有与图像视图相同的宽度和高度(例如,绘制背景/边框,可以设置为稍大一些)。
  • 图像容器视图被限制为以其超视图为中心(即NSScollView的剪辑视图)
  • 滚动视图被限制为填充窗口的contentView。

这些约束并不含糊,但我不明白为什么图像不居中?

Image not centered!

2 个答案:

答案 0 :(得分:3)

老问题,但这是一个不需要子类化的现代解决方案。这里涉及四种观点:

  • Scroll View是NSScrollView本身。
  • 剪辑视图是滚动视图中包含的NSClipView。
  • 内容视图是剪辑视图中的NSView。
  • 图像视图是用于显示内容的NSImageView。

所以这是过程:

  1. 创建滚动视图并将图像视图放在其内容视图中。
  2. 约束所有四个图像视图的边以等于内容视图的边。
  3. 将内容视图的前沿和上边缘限制为剪辑视图。
  4. 将内容视图的宽度和高度设置为大于或等于剪辑视图。
  5. 将图像视图的缩放比例设置为无,并将对齐设置为居中。
  6. 请注意,您可以使用或多或少的任何支持内容对齐和内在内容大小的内容替换NSImageView。或者,使用NSView,将其中的一些其他内容置于其中,并将该内容的顶部和左侧边缘固定到父级。这将允许NSView推断其最小尺寸,同时保持其子中心。

答案 1 :(得分:1)

鉴于您如何描述问题,这似乎是一个合理的结果。根据以上所述,你已经受到限制:

  • 图像包含视图被限制为具有与图像视图相同的宽度和高度(例如,绘制背景/边框,可以设置为稍大一些)。
  • 图像容器视图被限制为以其超视图为中心(即NSScollView的剪辑视图)
  • 滚动视图被限制为填充窗口的contentView。

NSScrollView不会使用自动布局在其内部布置视图。因此,通过将图像容器视图设置为图像的大小,当您的内容太小时,NSScrollView会将其固定到左下角(其原点)。

当我遇到同样的问题时,我做了两件事,每件事都需要一些工作,每一件事都合理成功:

  • 将包含视图的大小永远不小于NSScrollView的内容区域,然后将NSImageView置于该视图的中心。这会使包含视图内部自动居中,但需要您操纵包含视图的大小,以便在放大图像时没有边框。

  • 当包含的视图太小而无法填充NSScrollView时,移除NSScrollView并使窗口中包含视图居中。

无论哪种方式,您都需要注意窗口和NSScrollView的内容区域何时发生变化以及NSImageView的大小何时发生变化。