以编程方式设置动态uiimageview时出现LayoutConstraint错误

Posted

技术标签:

【中文标题】以编程方式设置动态uiimageview时出现LayoutConstraint错误【英文标题】:LayoutConstraint error when programmatically setting dynamic uiimageview 【发布时间】:2015-03-27 16:57:33 【问题描述】:

我有一个依赖于 iAdBanner 出现的 UIImageView 位置。我收到错误:

"<NSLayoutConstraint:0x17409eb40 UIImageView:0x1741e9200.bottom == UIView:0x17418d270.bottom - 100>",
"<NSLayoutConstraint:0x174281e00 UIImageView:0x1741e9200.bottom == UIView:0x17418d270.bottom - 50>"

关于造成这种情况的任何想法?下面是设置 uiimageview 的代码,根据 iAd 是否加载,设置它的高度。

    UIImageView *imgView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"sunshine.png"]];
    CGRect frame = imgView.frame;
    frame.size.width = 180;
    frame.size.height = 30;
    imgView.frame = frame;
    imgView.translatesAutoresizingMaskIntoConstraints = NO;

    [imgView setContentMode:UIViewContentModeScaleAspectFit];
    [imgView sizeToFit];
    [self.view addSubview:imgView];

    [self.view addConstraint:[NSLayoutConstraint
                              constraintWithItem:imgView
                              attribute:NSLayoutAttributeTrailing
                              relatedBy:NSLayoutRelationEqual
                              toItem:self.view
                              attribute:NSLayoutAttributeTrailing
                              multiplier:1.0
                              constant:6.0]];
    _imgView = imgView;



-(void)bannerViewDidLoadAd:(ADBannerView *)banner 
    [UIView beginAnimations:nil context:nil];
    [UIView setAnimationDuration:1];
    [banner setAlpha:1];
    [UIView commitAnimations];

        [self.view addConstraint:[NSLayoutConstraint
                                  constraintWithItem:_imgView
                                  attribute:NSLayoutAttributeBottom
                                  relatedBy:NSLayoutRelationEqual
                                  toItem:self.view
                                  attribute:NSLayoutAttributeBottom
                                  multiplier:1.0
                                  constant:-100.0]];



-(void)bannerView:(ADBannerView *)banner didFailToReceiveAdWithError:(NSError *)error 
    [UIView beginAnimations:nil context:nil];
    [UIView setAnimationDuration:1];
    [banner setAlpha:0];
    [UIView commitAnimations];

        [self.view addConstraint:[NSLayoutConstraint
                                  constraintWithItem:_imgView
                                  attribute:NSLayoutAttributeBottom
                                  relatedBy:NSLayoutRelationEqual
                                  toItem:self.view
                                  attribute:NSLayoutAttributeBottom
                                  multiplier:1.0
                                  constant:-50.0]];

【问题讨论】:

显示约束和错误日志。它会帮助我们更多。 您需要包含产生的 full 错误,以及用于创建约束的任何代码,或故事板中约束的屏幕截图。但从它的声音来看,你有两个相互矛盾的约束,不可能按照你想要的方式工作。 【参考方案1】:

据我了解,您的约束之间存在冲突,您应该删除两个约束之一。

【讨论】:

错误是关于 uiimageview 的底部和 uiview 底部,它没有我可以在情节提要中看到的约束。还有什么我应该去的地方吗?【参考方案2】:

问题是您添加了 2 次底部约束,一次在 -(void)bannerViewDidLoadAd:(ADBannerView *)banner 中,一次在 (void)bannerView:(ADBannerView *)banner didFailToReceiveAdWithError:(NSError *)error 方法中。约束具有不同的常量值(-100 和 -50),因此它们会崩溃。

这样做的正确方法是只添加一次约束,然后在 2 种方法中更改它的值。

类似这样的:

在添加尾随约束的第一种方法中,还要添加底部约束并保留对它的引用:

self.bottomOffsetConstraint = [NSLayoutConstraint
                                  constraintWithItem:_imgView
                                  attribute:NSLayoutAttributeBottom
                                  relatedBy:NSLayoutRelationEqual
                                  toItem:self.view
                                  attribute:NSLayoutAttributeBottom
                                  multiplier:1.0
                                  constant:-100.0];
[self.view addConstraint:self.bottomOffsetConstraint];

然后在 2 种方法中更改常量:

-(void)bannerViewDidLoadAd:(ADBannerView *)banner 
    [self.bottomOffsetConstraint setConstant:-50];
    [UIView beginAnimations:nil context:nil];
    [UIView setAnimationDuration:1];
    [banner setAlpha:1];
    // You need to call this in the animation block to trigger the constraints update
    [self.view layoutIfNeeded]; 
    [UIView commitAnimations];


-(void)bannerView:(ADBannerView *)banner didFailToReceiveAdWithError:(NSError *)error 

    [self.bottomOffsetConstraint setConstant:-50];
    [UIView beginAnimations:nil context:nil];
    [UIView setAnimationDuration:1];
    [banner setAlpha:0];
    [self.view layoutIfNeeded];
    [UIView commitAnimations];

这将修复崩溃的约束并为布局更改设置动画。

告诉我进展如何!

【讨论】:

同样的崩溃报告,你的意思是在 viewDidLoadAd 中输入 -100 吗?当 iAd 横幅出现时,图像不会重新定位。如果我可以提供更多代码,请告诉我... 嗯..这不应该发生。你能告诉我你添加约束的方法吗?启动应用时约束应该有什么值? 启动时应该是-50(较低的位置)并且它在viewWillAppear中。我原来的数字是倒着的,很抱歉造成混乱。现在它从正确的位置开始(下),出现 iads 并向上移动(很好!)。如果我重新回到视图,图像位于上部位置和下部位置。下一个移动到上一个。

以上是关于以编程方式设置动态uiimageview时出现LayoutConstraint错误的主要内容,如果未能解决你的问题,请参考以下文章

为啥以编程方式添加我的文本视图时出现 NullPointerException?

旋转 uiimageview 时出现问题

iOS 在 UITableViewCell 中以编程方式设置 UIImageView 约束在滚动 tableview 时变得混乱

调整大小后使用自动布局以编程方式居中 UIImageVIew

如何以编程方式在 Swift 中将 uiimageview 设置为 xcode 内置的 applewatch 图标图像?

以编程方式使用 UIImageView 自定义胶囊背景不起作用?