简体   繁体   English

更新imageView swift 4的高度约束时,无法同时满足约束

[英]Unable to simultaneously satisfy constraints when update height constraints of imageView swift 4

I have a stack view that look like the figure below: 我有一个stack view ,如下图所示:

在此处输入图片说明

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. 所以我改变的高度image编程,使其适合从我的服务器下载,如果不要有图像,高度约束的图像image将设置为零。

Here is my code to doing so: 这是我这样做的代码:

    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)

   }

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. 使用上面的代码,图像高度将根据从互联网下载的实际图像高度进行缩放。如果没有图像,则“图像”部分也已设置为0。

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. 在询问之前,我已经检查了所有其他约束,这些约束都已正确设置。我什至禁用了所有可以更改“图像”高度的代码,一旦禁用,就没有问题。错误仅在我打算更改时发生高度。

I even tried to add ImageView.translatesAutoresizingMaskIntoConstraints = false before layoutIfNeeded() ,but the error is still exist. 我什至尝试在layoutIfNeeded()之前添加ImageView.translatesAutoresizingMaskIntoConstraints = false ,但是错误仍然存​​在。

So what is the correct way to change the height of image in order to fit the actual image download from server? 那么,为了适应从服务器下载的实际图像,更改图像高度的正确方法是什么?

Considering that the last constraint says 考虑到最后一个约束说

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

I assume you are using stackView inside of a UITableViewCell to implement automatic height cells in a tableView . 我假设您正在UITableViewCell内部使用stackViewtableView实现自动高度单元。 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. 如果我的假设是正确的,那么这个问题是不是与stackView ,也不与imageView ,但与方式UITableView可与UITableViewAutomaticDimension和自动布局。 If the layout works as you expect, and the warning is the only thing that bugs you, then read following. 如果布局按预期工作,并且警告是唯一使您烦恼的事情,请阅读以下内容。

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. 因此在我看来,这是一个已知的“错误”的结果-存在通过设定高度的碰撞tableView并通过自动版式计算的高度。 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. 渲染单元格时, tableView首先应用默认高度,计算自动布局高度,然后使用后者-至少看起来如此。 See my question . 看看我的问题 The constraint mentioned above ( 'UIView-Encapsulated-Layout-Height' ) is the one applied by the UITableView that later goes away. 上面提到的约束( 'UIView-Encapsulated-Layout-Height' )是UITableView应用的约束,后来消失了。

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). 只需将定义高度的约束之一设置为priority = 999 (这样,在取消激活默认高度约束之前,不会引起任何冲突)。 In the end, it will result in using your constraint anyway, so it will not cause any layout trouble. 最后,它仍然会导致您使用约束,因此不会引起任何布局问题。

Eg, 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: 例如,如果将stackView约束为适合单元格的contentView ,则将stackView.bottomAnchor设置为contentView.bottomAnchor ,并且优先级设置为999。如果以编程方式进行布局,则这可能是您的解决方案:

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,
])

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

将约束的优先级设置为999

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM