NSImageView:水平适应容器宽度,垂直纵横比

Posted

技术标签:

【中文标题】NSImageView:水平适应容器宽度,垂直纵横比【英文标题】:NSImageView: horizontal fit-to-container-width, vertical aspect-scale 【发布时间】:2016-05-16 23:50:59 【问题描述】:

我希望在 NSScrollView 中嵌入一个 NSImageView,这样当调整 NSScrollView 的大小时,它的文档视图(即 NSImageView)会水平(向上或向下)调整大小以匹配 NSScrollView 的宽度,同时它的内容会被缩放以保持图像的纵横比。因此,NSImageView 可能会或可能不会被 NSScrollView 剪切,并且可能会进行垂直滚动。

这可能会让事情变得更清楚:如果我想要的在我的程序中的“查看”菜单下有一个菜单选项,它将标题为“缩放以适应水平”。

这是我所做的:

    在布局编辑器中创建一个 NSImageView。 使用“嵌入...”将其嵌入到 NSScrollView 中。 在 NSImageView 的属性编辑器中为“Scaling”选项启用“Proportionally Up or Down”。 添加约束以将 NSScrollView 的边距固定到其容器。 添加约束以将 NSImageView 的左侧和右侧固定到其容器。 将 NSImageView 的水平内容抗压缩优先级降低到 251。

NSScrollView 按预期调整大小。 NSImageView 的左右(或自动布局约束用语中的“前导”和“尾随”)边距被约束以匹配 NSScrollView。 NSImageView 中的图像将按比例缩小,使其适合 NSScrollView。当 NSScrollView 不够高而无法显示整个图像时,可以进行垂直滚动。

有两个问题。

首先,NSImageView 会根据需要增加其垂直尺寸以保持纵横比,但是当 NSScrollView 缩小时(即,因为包含窗口变小),NSImageView 永远不会减小其垂直尺寸.因此,图像上方和下方可能会有一堆空白区域。

我对这里发生的情况的可悲的消息不足的猜测是:当窗口增长时,布局引擎告诉 NSImageView 它会在水平方向变大,并且 NSImageView 看到它必须调整其内容的大小(因为它已经指示去做——步骤 3) 并说它会 喜欢 在垂直方向上更大。当窗口变小时,NSImageView 得知它会水平缩小,但它包含空白空间没有问题,所以它不会要求垂直变小。

我尝试过使用垂直内容压缩和拥抱优先级,以及在 NSImageView 上设置 =1(和 >=1)的低优先级高度约束,希望这会温和地鼓励它尽可能小在不与其他约束相矛盾的情况下可以做到这一点,但这样做告诉我我对自动布局的理解非常差。

当 NSImageView 得知其水平尺寸正在改变时,我是否需要以编程方式重置其垂直尺寸?

第二个问题是图像不会水平增长超过其自然大小。由于 NSImageView 被限制在其前缘/后缘以匹配其容器,并且由于它被告知要放大或缩小其内容,我什至无法开始猜测为什么会发生这种情况。

【问题讨论】:

我已经确定,当调整 NSImageView 的大小时,它的宽度会根据放置在其前缘和后缘上的约束而改变,但它的高度永远不会改变。它的高度设置为 unscaled 图像的高度。缩放图像时,内容高度似乎没有更新。 【参考方案1】:

在图像视图中的图像更新时以编程方式应用这些约束似乎可以解决问题:

float aspect = image.size.height / image.size.width;
[imageView.heightAnchor constraintEqualToAnchor:imageView.widthAnchor
                                     multiplier:aspect].active = YES;
[scrollView.superview.heightAnchor constraintLessThanOrEqualToAnchor:imageView.heightAnchor].active = YES;

这是对界面构建器中创建的以下约束的补充:

    图像 View.top = Superview.top 图像 View.leading = Superview.leading 图像 View.trailing = Superview.trailing Superview.bottom = 滚动 View.bottom - 1 Superview.top = 滚动 View.top - 1 Superview.leading = 滚动 View.leading - 1 Superview.trailing = 滚动 View.trailing - 1

【讨论】:

以上是关于NSImageView:水平适应容器宽度,垂直纵横比的主要内容,如果未能解决你的问题,请参考以下文章

图片裁剪自适应

高度自适应的水平垂直居中布局

如何制作垂直和水平居中的盒装div容器[重复]

bootstrap 行 100% 宽度,没有水平滚动和自适应每个尺寸

猫头鹰旋转木马纵横同高

当宽度未知时,将图像水平居中并将其垂直放置在 div 内的底部