自动布局一直在拉伸UIImageView

31

我正在使用自动布局,但它让我疯狂。我已经尽了一切努力来防止UIImageView被拉伸并覆盖整个页面,但不知道为什么它还是这样做了。我尝试使用约束和解决自动布局问题,但目前唯一的解决方法是关闭自动布局。

请问为什么Xcode完全忽略我的约束?我明确将UIImage的大小设置为320x320,但它仍然不遵循我的设置。

我想添加图片,但网站不允许我这样做,并且我想添加代码以使问题更具体,但实际上没有任何代码。我只是从Storyboard中拖动了"UIImageView",将其缩小,并设置了约束,但它仍然无视我的设置。


1
请定义“遍布全局”,并说明您已经尝试了什么。您设置了哪些限制? - mattyohe
你添加了哪些限制条件?听起来你在父视图的两侧(或上下取决于它被拉伸的方向)都有限制条件。 - rdelmar
这个问题不难重现。1:在Storyboard中将UIImageView放入UIView中。2:将其缩小,至少不要大于屏幕大小。3:编译并惊叹于它完全不起作用的情况。http://www.appcoda.com/ios-programming-camera-iphone-app/ 这个网站甚至建议关闭自动布局。如果我只是制作单个视图应用程序,我会这样做,但我不是,所以……我已经为UIImageView本身的大小添加了约束条件。而且Xcode完全、彻底地忽略了这个约束条件。结果就是我的屏幕上出现了一个丑陋的全屏拉伸图像。 - Gyuhyeon Lee
4
你的内容模式是什么?可能发生的情况是你的内容模式被设置成拉伸图像,而你没有将 clipsToBounds 设置为 YES。 - Travis
1
哦哇……那个……那个选项让我骂史蒂夫·乔布斯三个小时……哇……谢谢,现在我终于可以去睡觉了。谢谢你,你是个天才。 - Gyuhyeon Lee
@Travis:你应该截取一些设置的屏幕截图并将其发布为答案。这样Gyuhyeon Lee就可以接受它,而你也可以获得声望;)。 - GeneralMike
5个回答

49

您需要确保将 UIImageView 设置为裁剪视图。如果没有,图像将溢出视图并似乎无法正确拉伸(即使实际上是可以的)。

在界面构建器中,请确保勾选“剪切子视图”框。

输入图像描述

如果您不使用界面构建器,则以下代码将达到相同的效果:

yourImageView.clipsToBounds = YES;

虽然这个方法可以运行,但我仍然认为有一个 bug 存在——至少在文档中存在,如果不是在 UIImageView 本身。难道 clipsToBounds 的文档不是说要裁剪“子视图”吗?自从什么时候 UIImageView 中的图像被认为是子视图了呢? - DrMickeyLauer
4
在文档中,它们将其称为“基于视图的容器”——容器是让他们站稳脚跟的词。无论如何,UIKit文档总是不可靠和不一致的。 - Travis
3
人啊,你救了我的命!谢谢! - edzio27
2
哇...我差点要给霍格沃茨校长写信,请求让UIImageView表现出这种魔法,但是你救了我的一天。解决方案简单而明智。谢谢! - Artem Zaytsev
1
老实说,我从来没有像在SO上读到这个答案一样开心过。您是一个可靠的英雄先生。我差点把电脑扔出窗外了。 - A. Vin
我刚刚偶然发现了clipToBounds“解决方案”,并来到这里检查一下是否我失去了理智。即使按照UIKit的标准,这也是一个糟糕的API。 - Womble

7
使用自动布局时,Size Inspector 中的值基本上会被忽略。
如果在 Size Inspector 上输入数字,您可能会期望 Xcode 自动创建相应的约束以反映您的输入,但实际上并不会。 您需要自己创建 "Pin" 约束来设置 UIImageView 的高度和宽度。
以下是操作步骤:
1. 选择故事板中的图像视图。 2. 点击屏幕右下角的 "Pin" 按钮。 3. 在 "宽度" 和 "高度" 字段中输入所需的尺寸,并确保已经勾选了框。 4. 点击 "添加两个约束" 按钮。
完成后,您应该能够在屏幕右侧的大小检查器中看到您的约束(紫色框)。

1
谢谢您的回答,我已经做了所有的事情。事实证明,ImageView 没有被拉伸,视图中导入的图像在视图外被裁剪。常识告诉我们,默认情况下,内容通常会停留在视图内部,但看来并非如此。通过勾选「夹子子视图」解决了这个问题。业余的错误,确实如此。 - Gyuhyeon Lee
@GyuhyeonLee:如果你刚开始学习iOS编程,请不要假设任何东西会自动发生 - 根据我的经验,它几乎从来不会按照我所想象的那样运行。但很高兴你找到了解决方案! - GeneralMike

6

我的问题出现在 ContentHuggingPriorityContentCompressionResistancePriority 上。

前者控制视图“紧贴”图像的重要程度(保持接近并且不扩展),而后者控制视图对压缩的抵抗力。

我们使用 PureLayout,所以修复问题的代码如下:

[NSLayoutConstraint autoSetPriority:ALLayoutPriorityRequired forConstraints:^{
    [myImageView autoSetContentCompressionResistancePriorityForAxis:ALAxisHorizontal];
    [myImageView autoSetContentHuggingPriorityForAxis:ALAxisHorizontal];
}];

我的问题只出现在水平轴上。

2016年5月15日:更新为PureLayout v3语法。如果您使用版本<=2,则将UIView替换为NSLayoutConstraint。感谢Rudolf J


这是一个很好的解决方案。PureLayout现在已经将其更改为[NSLayoutConstraint autoSetPriority....然而... - Rudolf J

4

我曾经遇到同样的问题。我在原型单元格中添加了一个 UIImageView,并希望将其与文本对齐,但是当应用约束时,它会拉伸图像。在我的情况下,我将图像视图的“Mode”属性更改为“Aspect Fit”,然后它就可以正常工作了。enter image description here


遇到了完全相同的问题。使用Aspect Fit内容模式解决了它。仍然不知道为什么它不能正确地工作。 - batman

0
你可以尝试以编程方式添加UIImageView。 在你的viewDidLoad方法或者你想要的地方调用这段代码。
UIImageView *yourImageView = [[UIImageView alloc]initWithFrame:CGRectMake(50.0f, 50.0f, 320.0f, 320.0f)]; // x and y coordinates, width and height of UIImageView
[yourImageView setImage:[UIImage imageNamed:@"your_image.png"]];
[yourImageView setContentMode:UIViewContentModeCenter]; // you can try use another UIViewContentMode

[self.view addSubview:yourImageView];

谢谢你的回答,我尝试了一下,但它仍然变得非常非常大。UIImageView是一个实际的视图,就像一个窗口,还是只是可以被任何东西覆盖的临时物品?也就是说,如果我将一个320x320的图像放入一个240x240的imageview中,它会变大吗? - Gyuhyeon Lee
你可以尝试使用:[yourImageView setContentMode:UIViewContentModeCenter]; 有关UIViewContentMode的更多信息 - Ilya Dmitriev

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接