Как установить NSLayoutAnchor для генерации центрированного подпредставления с соотношением сторон 1:1

Звучит не сложно, но после нескольких часов попыток я не смог найти правильного решения.

Проблема: я хочу установить ограничения (с классом NSLayoutAnchor), чтобы получить подпредставление (colorImageView), центрированное в суперпредставлении, с соотношением сторон 1:1 И всегда с максимально возможным размером в суперпредставлении, которое иногда имеет ширину> высоту ИЛИ высота> ширина.

Пример 1: SuperViewSize = ширина: 80, высота = 100 -> подпредставление должно получить высоту и ширину 80 с центром в (40/50)

Пример 2: SuperviewSize = ширина: 60, высота = 50 -> подпредставление должно получить высоту и ширину 50 с центром в (30/25)

Я не хочу / и это не решает проблему / жестко закодировать widthConstraint = min(superviewWidth, superviewHeight), потому что в момент создания подпредставления границы суперпредставлений не определены окончательно -> поэтому мне нужно ограничение.

Это моя попытка (до сих пор не хватает ограничений, чтобы установить максимальную высоту и ширину в пределах изменяющегося суперпредставления:

// CREATE CONSTRAINTS(center in SuperView)
colorImageView.centerXAnchor.constraint(equalTo: self.centerXAnchor).isActive = true
colorImageView.centerYAnchor.constraint(equalTo: self.centerYAnchor).isActive = true

// CREATE CONSTRAINTS (ratio 1:1)
colorImageView.widthAnchor.constraint(equalTo: colorImageView.heightAnchor, multiplier: 1.0).isActive = true

Я очень ценю подсказку, как это сделать. Заранее спасибо:))

1 ответ

Решение

Ключом к созданию этой работы является установка ширины colorImageView равна ширине его суперпредставления, но с приоритетом 750 (вместо значения по умолчанию 1000).

Затем установите высоту colorImageView быть lessThanOrEqualTo высота его суперпредставления.

Auto Layout сделает все возможное, чтобы удовлетворить эти два новых ограничения.

Когда ширина представления больше его высоты, он не сможет colorImageViews ширина равна ширине представления, но это нормально, так как приоритет равен 750. Это сделает его максимально большим, не нарушая другие ограничения полного приоритета.

Когда высота представления превышает его ширину, он сможет удовлетворить все ограничения, потому что высота colorView lessThanOrEqualTo высота вида.

import UIKit

let view = UIView(frame: CGRect(x: 0, y: 0, width: 80, height: 100))
view.backgroundColor = .red

let colorImageView = UIView()
colorImageView.translatesAutoresizingMaskIntoConstraints = false
colorImageView.backgroundColor = .yellow

view.addSubview(colorImageView)

// CREATE CONSTRAINTS(center in SuperView)
colorImageView.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
colorImageView.centerYAnchor.constraint(equalTo: view.centerYAnchor).isActive = true

// CREATE CONSTRAINTS (ratio 1:1)
colorImageView.widthAnchor.constraint(equalTo: colorImageView.heightAnchor, multiplier: 1.0).isActive = true

let widthConstraint = colorImageView.widthAnchor.constraint(equalTo: view.widthAnchor)
widthConstraint.priority = 750
widthConstraint.isActive = true

colorImageView.heightAnchor.constraint(lessThanOrEqualTo: view.heightAnchor).isActive = true

view.layoutIfNeeded()

view.frame = CGRect(x: 0, y: 0, width: 60, height: 50)
view.layoutIfNeeded()

Вот он работает на детской площадке:

введите описание изображения здесь

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