【问题标题】:cannot modify frame of UIImageView if added through Interface Builder如果通过 Interface Builder 添加,则无法修改 UIImageView 的框架
【发布时间】:2013-09-28 12:19:09
【问题描述】:

我遇到了一个非常特殊的问题,我无法修改 UIImageView 的框架。

我已将其隔离到这个非常简单的示例中。从默认的单视图应用程序 xcode 模板开始,我在 Interface Builder 中添加了一个 UIImageView,将其链接到名为 testImage 的 ViewController 属性,然后在 ViewController.m 中添加:

-(void)viewDidAppear:(BOOL)animated{
    UIImageView* maskImage = [[UIImageView alloc] initWithFrame:self.testImage.frame];
    maskImage.image = self.testImage.image;
    maskImage.alpha = 0;
    [self.view addSubview:maskImage];
    self.testImage.frame = CGRectMake(10, 10, 10, 10);
}

它不起作用。测试图像坚定地保持在原来的位置。如果我不添加 maskImage 来查看,则该示例有效。而且,是的,我确定我没有用 maskImage 覆盖目的地。

如果我不使用 IB 来放置图像,而是使用:

self.testImage = [[UIImageView alloc] initWithFrame:CGRectMake(0, 100, 300, 300)];
self.testImage.image = [UIImage imageNamed:@"jim-105.png"];
[self.view addSubview:self.testImage];

在 viewDidLoad 中,一切都按预期工作。

我也尝试将图像放在 IB 中,然后在 viewDidLoad 中设置其属性,但效果相同。我一直在 Xcode5 中尝试这个。我在这里无法访问以前的 Xcode,我不确定这是预期的行为(如果是,为什么)或者这是一个错误?

【问题讨论】:

  • 在你的第一个例子中,self.testImage nil?
  • 不,不是。我在 IB 中设置的。
  • 如果在viewDidAppear方法的最后一行前后加上NSLog(@"testImage: %@", self.testImage);,会显示什么?
  • testImage: > testImage: > 但图像仍保留在屏幕上的位置...我可以更改它的其他属性。例如,如果我更改它的 contentMode 或 backgroundColor,它会按预期显示。
  • 我从头开始修改了这个例子。现在我确实有自动布局(就像我在我第一次体验这个的原始应用程序中所做的那样)。我还在 IB 中设置了对 testImageViw 的约束。并且代码的行为相同。如果我不使用 addSubview 添加 maskImage,则测试图像会调整大小。让我感到困惑的是,其中之一是不正确的。它要么服从约束,要么不服从。如果我将兄弟姐妹添加到超级视图,为什么它只会遵守约束?

标签: ios uiimageview interface-builder


【解决方案1】:

如果您使用自动布局,我希望您所描述的行为准确无误,其中在重新应用约束时可能会阻止调整 frame 的尝试(这可能发生在最偶然的事件中,例如添加另一个查看到主视图)和frame 将被重新计算。如果你有一个带有约束的自动布局视图,要改变它的大小,你就要改变它的约束。

如果您想知道为什么以编程方式创建的 testImage 会按预期工作,这是因为默认情况下,以编程方式创建的视图已打开 translatesAutoresizingMaskIntoConstraints。因此,更改 frame 的尝试仍然存在。

如果您使用自动布局并想要更改 frame,您可以通过在 Interface Builder 中为约束添加 IBOutlet 引用来完成此操作。假设您的视图有顶部、前导、宽度和高度约束。然后你可以改变它的框架(在这个例子中,为CGRect(0, 100, 300, 200)):

self.imageViewLeadingConstraint.constant = 0;
self.imageViewTopConstraint.constant = 300.0;
self.imageViewWidthConstraint.constant = 300;
self.imageViewHeightConstraint.constant = 200;

显然,您需要这四个 IBOutlet 引用,但是一旦这样做,就很容易了。

【讨论】:

  • 不,我不使用自动布局。即使我这样做了,如果我不添加 maskView,该示例也可以正常工作。添加 UIImageView 的副本使其粘住。只有当我在 IB 中添加原始图像时。
  • @nekiTamoTip 如果您启用了自动布局,当您添加maskImage 时,可能会重新应用约束,并且将重新计算testImageframe。对于 IB 添加的testImage,这意味着它返回到原始位置。对于您在代码中创建的testImage,您已打开translatesAutoresizingMaskIntoConstraints(默认情况下),因此新的frame 将起作用。对我来说,关闭自动布局后,您的代码可以与 IB 中添加的 testImage 一起正常工作。
  • 非常感谢 Rob,这个解释对我很有帮助。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-07-05
  • 1970-01-01
  • 1970-01-01
  • 2023-04-06
  • 2011-11-30
相关资源
最近更新 更多