Невозможно одновременно удовлетворить ограничения при обновлении ограничений высоты imageView swift 4

У меня есть stack view это похоже на рисунок ниже:

Так что я меняю высоту 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)>"
)

Перед тем как спросить, я уже проверил все остальные свои ограничения, которые все установлены правильно. Я даже отключаю весь код, который может изменять высоту "изображения", после отключения проблем нет. Ошибка возникала только тогда, когда я намеревался изменить высота.

Я даже пытался добавить ImageView.translatesAutoresizingMaskIntoConstraints = false до layoutIfNeeded(), но ошибка все еще существует.

Итак, как правильно изменить высоту изображения, чтобы оно соответствовало фактической загрузке изображения с сервера?

1 ответ

Решение

Учитывая, что последнее ограничение говорит

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

Я полагаю, вы используете stackView внутри UITableViewCell реализовать автоматическую высоту ячеек в tableView, Если мое предположение верно, то проблема не в stackViewни с imageView, но со способом UITableView работает с UITableViewAutomaticDimension и Autolayout. Если раскладка работает так, как вы ожидаете, и единственное, что вас беспокоит, - предупреждение, прочитайте следующее.

Поэтому мне кажется, что это результат известной "ошибки" - столкновение высоты, установленной tableView и высота, рассчитанная по автопутешествию. При рендеринге ячейки tableView сначала применяет высоту по умолчанию, вычисляет высоту авторазметки, а затем использует последний - по крайней мере, так кажется. Смотри мой вопрос. Ограничение, упомянутое выше ('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,
])

Если вы делаете макет в раскадровках, просто выберите соответствующее ограничение в раскадровках, а в инспекторе атрибутов установите его приоритет 999 (например):

Ограничение приоритета настроек до 999

Другие вопросы по тегам