使用 Interface Builder 中的 Auto Layout 启用 NSScrollView 滚动其内容 [英] Enabling NSScrollView to scroll its contents using Auto Layout in Interface Builder

查看:15
本文介绍了使用 Interface Builder 中的 Auto Layout 启用 NSScrollView 滚动其内容的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经实现了一个自定义 NSView,其中包含许多 NSTextField 和其他 NSView.然后,我使用 Editor > Embed In > Scroll View 将该自定义视图嵌入到滚动视图中.这将创建在大纲中可见的适当层次结构,但我需要添加自动布局约束以指定此滚动视图应放置在视图中的位置(顶部、底部、前导、尾随).此外,我必须为自定义视图添加约束,针对剪辑视图设置,以便将元素布置在正确的位置.这很好用,当我运行应用程序时,所有元素都会正确显示,并且视图会反弹滚动.但是,当我降低主视图的高度以使并非所有元素都适合屏幕时,会出现自动布局警告,并且当我更新框架时,它会再次增加视图的高度.为了解决这个问题,我不得不将滚动视图的底部约束移除到主视图.现在,当我运行应用程序时,窗口设置为正确的大小,但我无法滚动自定义视图以到达内容的底部 - 它受到限制,因此除了弹性反弹效果之外它根本不会滚动,因为你'重新处于边缘极限.所以我的问题是,当我在 XIB 中布局所有元素并使用自动布局时,我必须做什么才能让这个滚动视图滚动?

I have implemented a custom NSView which contains many NSTextFields and other NSViews. I then embedded that custom view in a scroll view using Editor > Embed In > Scroll View. This creates the appropriate hierarchy as visible in the Outline, but I needed to then add Auto Layout constraints to specify where this scroll view should be placed within the view (top, bottom, leading, trailing). Additionally I had to add constraints for the custom view, set against the clip view, in order to lay out the elements in the correct location. This works well, when I run the app all the elements appear appropriately and the view does bounce scroll. However, when I reduce the height of the main view so that that not all of the elements fit on screen, auto layout warnings appear and when I update the frames it increases the height of the view again. To fix that, I had to remove the scroll view's bottom constraint to the main view. Now when I run the app, the window is set to the right size, but I cannot scroll the custom view to get to the bottom of the content - it's restricted so it won't scroll at all besides the elastic bounce effect because you're at the edge limit. So my question is, what must I do in order to allow this scroll view to scroll when I'm laying out all elements in a XIB and using Auto Layout?

推荐答案

一般做法如下:

  • 使文档视图至少与剪辑视图一样高.或者,等效地,使剪辑视图不高于文档视图.
  • 允许文档视图增加高度,但不要缩小到超出其子视图所需的高度.
  • 通过设置低优先级约束来防止文档视图中的歧义,以便在考虑其他约束的情况下使其尽可能小.

因此,例如,剪辑视图的底部和文档视图的底部之间应该有一个约束,但它应该是一个不等式:Superview.Bottom <= Document View.Bottom.(或者,等效地,Document View.Bottom >= Superview.Bottom.)

So, for example, there should be a constraint between the clip view's bottom and the document view's bottom, but it should be an inequality: Superview.Bottom <= Document View.Bottom. (Or, equivalently, Document View.Bottom >= Superview.Bottom.)

在文档视图中,您可能在底部有一些文本字段或其他东西,并且它与文档视图的底部之间存在约束.使该约束成为不等式:Superview.Bottom >= Text Field.Bottom + 标准间距.

Within the document view, you probably have some text field or something at the bottom and a constraint between that and the document view's bottom. Make that constraint an inequality: Superview.Bottom >= Text Field.Bottom + standard spacing.

这将导致文档视图的高度不明确.它可以是任何大小,足以容纳其所有子视图.添加高度约束.将其优先级设置为 51,将其常量设置为 0.也就是说,它想让视图的高度为 0,但优先级非常低,因此几乎任何其他东西都会取代它.但它解决了歧义.

That will cause ambiguity as to the height of the document view. It could be any size tall enough to fit all of its subviews. Add a height constraint. Set its priority to 51 and its constant to 0. That is, it wants to make the view have 0 height, but at very low priority so almost anything else will supersede it. But it resolves the ambiguity.

如果你想允许水平滚动,你需要在水平方向上做同样的事情.

If you want to allow horizontal scrolling, you need to do the same general thing in the horizontal orientation.

更新:

还有另一种方法.配置文档视图中的约束,使其具有严格的大小(没有不等式).这通常是从其顶部到顶部子视图、从该子视图的底部到另一个子视图的顶部等以及从底部子视图的底部到文档视图的底部的一系列约束.导致尾随也是如此.

There's another approach. Configure the constraints within the document view to give it a strict size (no inequalities). That's usually a chain of constraints from its top to the top subview, from that subview's bottom to the top of another subview, etc., and from the bottom of the bottom subview to the document view's bottom. Same for leading to trailing.

那么,剪辑视图和文档视图之间唯一必要的约束是顶部和前导约束.

Then, the only necessary constraints between the clip view and the document view are top and leading constraints.

如果您在此配置中进行测试,您将能够调整大小并且滚动视图将滚动.所以,这很好.但是,当滚动视图的内容区域高于文档视图时,文档视图将固定在内容区域的底部.在这种情况下,您通常希望将其固定在顶部.

If you test in this configuration, you'll be able to resize and the scroll view will scroll. So, that's good. However, when the scroll view's content area is taller than the document view, the document view will be pinned to the bottom of the content area. You usually want it pinned to the top in that situation.

原因是剪辑视图没有翻转.此外,它正在调整其边界以匹配文档视图.因此,即使将文档视图固定在剪辑视图的顶部存在约束,剪辑视图的顶部也不是您期望的位置.剪辑视图将文档视图置于底部的 (0, 0).

The reason is that the clip view is not flipped. Also, it's adjusting its bounds to match the document view. So, even though there's a constraint to keep the document view pinned to the top of the clip view, the top of the clip view isn't where you expect it to be. The clip view puts the document view at (0, 0), which is at the bottom.

所以,最后一步是创建一个 NSClipView 的子类,它覆盖 -isFlipped 以返回 YES.然后,将 NIB 中的剪辑视图的类设置为您的子类.之后,它将按您的意愿工作.

So, the final piece is to create a subclass of NSClipView that overrides -isFlipped to return YES. Then, set the class of the clip view in the NIB to your subclass. After that, it will work as you want.

这篇关于使用 Interface Builder 中的 Auto Layout 启用 NSScrollView 滚动其内容的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆