更新imageView swift 4的高度约束时,无法同时满足约束 [英] Unable to simultaneously satisfy constraints when update height constraints of imageView swift 4

查看:213
本文介绍了更新imageView swift 4的高度约束时,无法同时满足约束的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个stack view,如下图所示:

I have a stack view that look like the figure below:

因此,我以编程方式更改image的高度,以使其适合从服务器下载的图像,如果没有图像,则image的高度限制将设置为零.

So I change the height of the image programmatically to make it fit the image that download from my server,if dont have image,the height constraints of image will set to be zero.

这是我这样做的代码:

    let imageUrl = URL(string :imageString)

    if let data = try? Data(contentsOf: imageUrl!)
    {

       guard let actualImage: UIImage = UIImage(data: data) else{
        print("No image!")
        ImageView.image = nil
       defaultImageHeightContrainst = ImageHeightContrainst.constant
       ImageHeightContrainst.constant = 0

        layoutIfNeeded()
        return
      }

     let imageHeight = actualImage.size.height * actualImage.scale
     print("imageHeight = \(imageHeight)")
     defaultImageHeightContrainst = ImageHeightContrainst.constant
     ImageHeightContrainst.constant = imageHeight

     layoutIfNeeded()

     //here display the image to the imageview
      ImageView.kf.setImage(with: imageUrl)

   }

使用上面的代码,图像高度根据从互联网下载的实际图像高度缩放.如果没有图像,则图像"部分也已设置为0.

With the code above,the image height is scale according to actual image height which download from internet.If dont have image,the "image" part also set to 0 already.

这是我的预期,但是现在每当图像"高度变高以适合实际图像高度时,我都会在下面遇到错误

This is what I expected,but now I face an error below whenever the "image" height become taller in order to fit the actual image height

 Probably at least one of the constraints in the following list is one you don't want. 
    Try this: 
        (1) look at each constraint and try to figure out which you don't expect; 
        (2) find the code that added the unwanted constraint or constraints and fix it. 
(
    "<NSLayoutConstraint:0x6080002868b0 UIImageView:0x7f9cbae59240.height == 50   (active)>",
    "<NSLayoutConstraint:0x608000286bd0 UIView:0x7f9cbae5ad80.height == 1   (active)>",
    "<NSLayoutConstraint:0x608000286d10 UIImageView:0x7f9cbae5b440.height == 458   (active)>",
    "<NSLayoutConstraint:0x608000286f90 UIView:0x7f9cbae5bb50.height == 1   (active)>",
    "<NSLayoutConstraint:0x6080002871c0 V:|-(0)-[UILabel:0x7f9cbae5b160]   (active, names: '|':UIStackView:0x7f9cbae5af60 )>",
    "<NSLayoutConstraint:0x608000287350 V:[UILabel:0x7f9cbae5b160]-(10)-[UIImageView:0x7f9cbae5b440]   (active)>",
    "<NSLayoutConstraint:0x6080002873a0 V:[UIImageView:0x7f9cbae5b440]-(10)-[UIStackView:0x7f9cbae5b670]   (active)>",
    "<NSLayoutConstraint:0x608000287580 V:[UIStackView:0x7f9cbae5b670]-(10)-[UIView:0x7f9cbae5bb50]   (active)>",
    "<NSLayoutConstraint:0x6080002875d0 V:[UIStackView:0x7f9cbae5c0f0]-(0)-|   (active, names: '|':UIStackView:0x7f9cbae5af60 )>",
    "<NSLayoutConstraint:0x608000287670 V:[UIView:0x7f9cbae5bb50]-(10)-[UIStackView:0x7f9cbae5c0f0]   (active)>",
    "<NSLayoutConstraint:0x6080002877b0 V:|-(10)-[UIImageView:0x7f9cbae59240]   (active, names: '|':UITableViewCellContentView:0x7f9cbae5a0c0 )>",
    "<NSLayoutConstraint:0x6080002878f0 V:[UIImageView:0x7f9cbae59240]-(8)-[UIView:0x7f9cbae5ad80]   (active)>",
    "<NSLayoutConstraint:0x6080002879e0 V:[UIStackView:0x7f9cbae5af60]-(10)-|   (active, names: '|':UITableViewCellContentView:0x7f9cbae5a0c0 )>",
    "<NSLayoutConstraint:0x608000287a80 V:[UIView:0x7f9cbae5ad80]-(8)-[UIStackView:0x7f9cbae5af60]   (active)>",
    "<NSLayoutConstraint:0x608000288c00 'UISV-canvas-connection' UIStackView:0x7f9cbae5c0f0.top == _UILayoutSpacer:0x6080001cd5c0'UISV-alignment-spanner'.top   (active)>",
    "<NSLayoutConstraint:0x608000288ca0 'UISV-canvas-connection' V:[_UILayoutSpacer:0x6080001cd5c0'UISV-alignment-spanner']-(0)-|   (active, names: '|':UIStackView:0x7f9cbae5c0f0 )>",
    "<NSLayoutConstraint:0x608000289970 'UIView-Encapsulated-Layout-Height' UITableViewCellContentView:0x7f9cbae5a0c0.height == 476.5   (active)>"
)

在询问之前,我已经检查了所有其他约束,这些约束都已正确设置.我什至禁用了所有可以更改图像"高度的代码,一旦禁用,就没有问题.错误仅在我执行时发生打算改变高度.

Before asking,I already checked all my other constraints,which is all set correctly.I even disable all the code that can change the height of "image",once disable,there is no problem.The error only occurred when I intend to change the height.

我什至尝试在layoutIfNeeded()之前添加ImageView.translatesAutoresizingMaskIntoConstraints = false,但是错误仍然存​​在.

I even tried to add ImageView.translatesAutoresizingMaskIntoConstraints = false before layoutIfNeeded(),but the error is still exist.

那么为了适应从服务器下载的实际图像,改变图像高度的正确方法是什么?

So what is the correct way to change the height of image in order to fit the actual image download from server?

推荐答案

考虑到最后一个约束说

"<NSLayoutConstraint:0x608000289970 'UIView-Encapsulated-Layout-Height' UITableViewCellContentView:0x7f9cbae5a0c0.height == 476.5   (active)>"

我假设您在UITableViewCell内使用stackViewtableView中实现自动高度单元.如果我的假设是正确的,那么问题就出在stackViewimageView上,而不是UITableViewUITableViewAutomaticDimension和Autolayout上的工作方式.如果布局按预期工作,并且警告是唯一使您烦恼的事情,请阅读以下内容.

I assume you are using stackView inside of a UITableViewCell to implement automatic height cells in a tableView. If my assumption is correct, then the problem is not with the stackView, nor with the imageView, but with the way UITableView works with UITableViewAutomaticDimension and Autolayout. If the layout works as you expect, and the warning is the only thing that bugs you, then read following.

因此,在我看来,这是已知的错误"的结果-tableView设置的高度与自动布局所计算的高度发生了冲突.渲染单元格时,tableView首先应用默认高度,计算自动布局高度,然后使用后者-至少看起来如此.请参阅我的问题.上述约束('UIView-Encapsulated-Layout-Height')是UITableView应用的约束,后来消失了.

Therefore it seems to me that this is a result of an known "bug" - there is a collision of the height set by the tableView and the height calculated by the autolayout. When rendering the cell, the tableView first applies the default height, calculates the autolayout height, and then use the latter - at least it seems so. See my question. The constraint mentioned above ('UIView-Encapsulated-Layout-Height') is the one applied by the UITableView that later goes away.

这意味着您正在使用的约束可能还可以.只需将定义高度的约束之一设置为priority = 999(这样,在取消激活默认的高度约束之前,不会引起任何冲突).最后,它仍然会导致您使用约束,因此不会造成任何布局麻烦.

That means that the constraints you are using are probably OK. Just set one of the constraints defining height to priority = 999 (so that until it deactivates the default height constraint it won't cause any conflict). In the end, it will result in using your constraint anyway, so it will not cause any layout trouble.

例如,如果约束stackView以适合单元格的contentView,则将stackView.bottomAnchor设置为contentView.bottomAnchor,而优先级设置为999.如果以编程方式进行布局,则可能是您的解决方案:

E.g., if you constrain the stackView to fit the cell's contentView, set the stackView.bottomAnchor to contentView.bottomAnchor just with the priority set to 999. If you did the layout programmatically, this might be your solution:

let bottomConstraint = tableView.bottomAnchor.constraint(equalTo: view.bottomAnchor)
bottomConstraint.priority = UILayoutPriority(rawValue: 999)
NSLayoutConstraint.activate([
    // rest of the constraints
    stackView.topAnchor.constraint(equalTo: contentView.topAnchor),
    stackView.leftAnchor.constraint(equalTo: contentView.leftAnchor),
    stackView.rightAnchor.constraint(equalTo: contentView.rightAnchor),
    bottomConstraint,
])

如果在情节提要中进行布局,只需在情节提要中选择适当的约束,然后在属性检查器中将其优先级设置为999(例如):

If you do the layout in storyboards, just select appropriate constraint in the storyboards, and in the attributes inspector set its priority to 999 (for example):

这篇关于更新imageView swift 4的高度约束时,无法同时满足约束的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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