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

标签 ios tableview swift4 uistackview

我有一个如下图所示的堆栈 View :

enter image description here

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

这是我的代码:

    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。

这是我所期望的,但现在每当“图像”高度变高以适应实际图像高度时,我都会遇到以下错误

 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)>"
)

在询问之前,我已经检查了所有其他约束,这些约束都设置正确。我什至禁用了所有可以更改“图像”高度的代码,一旦禁用,就没有问题了。只有当我打算改变高度。

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

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

最佳答案

考虑到最后一个约束说

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

我假设您正在 UITableViewCell 内部使用 stackView 来实现 tableView 中的自动高度单元格。如果我的假设是正确的,那么问题不在于 stackView,也不在于 imageView,而在于 UITableView 配合使用的方式>UITableViewAutomaticDimension 和自动布局。如果布局按您的预期工作,并且警告是唯一让您烦恼的事情,那么请阅读以下内容。

因此,在我看来,这是一个已知“错误”的结果 - tableView 设置的高度与自动布局计算的高度存在冲突。渲染单元格时,tableView 首先应用默认高度,计算自动布局高度,然后使用后者 - 至少看起来是这样。看我的question 。上面提到的约束 ('UIView-Encapsulated-Layout-Height') 是由 UITableView 应用的约束,后来消失了。

这意味着您使用的约束可能没问题。只需将定义高度的约束之一设置为 priority = 999(这样,在停用默认高度约束之前,不会导致任何冲突)。最终,无论如何它都会导致使用您的约束,因此不会造成任何布局问题。

例如,如果您限制 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,
])

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

Settings constraint's priority to 999

关于ios - 更新 imageView swift 4 的高度约束时无法同时满足约束,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48128628/

相关文章:

Javascript 相当于 iOS 的 'tap' 事件,但适用于 android

ios - Swift 3 iOS -Google GMSAutoComplete 自升级后出现故障

ios - 为同一应用程序中的不同屏幕制作可重用表格 View 的最佳方法是什么?

swift - 如何使用 "#selector"发送参数

ios - 无法将类型 '(_) -> ()?' 的值转换为预期的参数类型 '@convention(block) () -> Void'

json - Codable 与 swiftyjson。如何将我的代码转换为 Codable(值数组)

ios - 使用 RESTKit 映射带有括号的 JSON 响应

ios - 重用 CCLabelTTF

ios - 无法使用 dequeueReusableCell(withIdentifier : for:) from a xib file

iOS:将表格单元格移动到另一个部分