Невозможно одновременно удовлетворить ограничения при обновлении ограничений высоты 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 (например):