У вас пара вещей идет не так, как надо.
Использование страницы игровой площадки с двумя метками "как есть", если вы измените текст label2
на:
label2.text = "01234567890 ABCDEFGHIJ"
Вы получите это:

Как видите, наличие двух меток не "решает проблему" ... это просто так, потому что вы использовали очень короткую строку для второй метки.
Что происходит, когда: автоматическое расположение обрабатывает ограничения и обнаруживает, что оно не может полностью удовлетворить все из них, оно использует приоритеты, чтобы определить, какие из них можно нарушить, не выдавая ошибку. В вашем случае вы устанавливаете различные ограничения и приоритеты, которые неверны , предоставляя автоматическому макету разрешение на изменение макета.
Итак, во-первых, я не знаю, откуда у вас возникла идея установить приоритет для topologyView
ограничений на ведение, трейлинг, верх и низ на .defaultLow
. в явном виде предписывает автоматическому макету игнорировать эти ограничения, если это необходимо. Затем вы добавляете метку, которая будет шире topologyView
, и автоматическая разметка будет следовать вашим инструкциям и нарушит ограничения.
В вашем примере с «двумя метками» автоматическое расположение отдает приоритет label2
- что просто произошло , чтобы сделать его правильным (пока вы не сделаете метку шире).
Далее, вы используете greaterThanOrEqualTo
неправильно. Установив:
topologyView.trailingAnchor.constraint(greaterThanOrEqualTo: containerView.trailingAnchor)
вы говорите: "позвольте заднему фронту topologyView
перейти за заднему фронту containerView
. Что вы действительно хотите, это меньше :
topologyView.trailingAnchor.constraint(lessThanOrEqualTo: containerView.trailingAnchor)
Это сохранит задний край topologyView
меньше задний край containerView
.
Теперь неясно, хотите ли вы, чтобы метки помещались на всю ширину containerView
, или если вы хотите, чтобы они центрировались, если они оба короткие.
Если полная ширина, используйте equalTo
... если отцентрировано, используйте greatThanOrEqualTo
в начале и lessThanOrEqualTo
в конце.
То же самое относится и к нижнему ограничению.
Итак ... ваш пример "одного ярлыка" становится:
import UIKit
import Foundation
import PlaygroundSupport
let viewController = UIViewController()
viewController.view.backgroundColor = UIColor.green
let containerView = UIView()
containerView.backgroundColor = .gray
containerView.translatesAutoresizingMaskIntoConstraints = false
viewController.view.addSubview(containerView)
containerView.widthAnchor.constraint(equalToConstant: 200).isActive = true
containerView.heightAnchor.constraint(equalToConstant: 200).isActive = true
containerView.centerXAnchor.constraint(equalTo: viewController.view.centerXAnchor).isActive = true
containerView.centerYAnchor.constraint(equalTo: viewController.view.centerYAnchor).isActive = true
let topologyView = UIView()
topologyView.backgroundColor = .blue
topologyView.translatesAutoresizingMaskIntoConstraints = false
containerView.addSubview(topologyView)
let leadingConstraint = topologyView.leadingAnchor.constraint(greaterThanOrEqualTo: containerView.leadingAnchor)
// use default priority
//leadingConstraint.priority = .defaultLow
leadingConstraint.isActive = true
// use lessThanOrEqualTo
let trailingConstraint = topologyView.trailingAnchor.constraint(lessThanOrEqualTo: containerView.trailingAnchor)
// use default priority
//trailingConstraint.priority = .defaultLow
trailingConstraint.isActive = true
let topConstraint = topologyView.topAnchor.constraint(greaterThanOrEqualTo: containerView.topAnchor)
// use default priority
//topConstraint.priority = .defaultLow
topConstraint.isActive = true
// use lessThanOrEqualTo
let bottomConstraint = topologyView.bottomAnchor.constraint(lessThanOrEqualTo: containerView.bottomAnchor)
// use default priority
//bottomConstraint.priority = .defaultLow
bottomConstraint.isActive = true
topologyView.centerXAnchor.constraint(equalTo: containerView.centerXAnchor).isActive = true
topologyView.centerYAnchor.constraint(equalTo: containerView.centerYAnchor).isActive = true
let label1Title = "1234"
let label1 = UILabel()
label1.backgroundColor = .yellow
label1.translatesAutoresizingMaskIntoConstraints = false
label1.text = Array(repeating: label1Title, count: 10).joined()
// we can leave Hugging and Compression at default Priority
//label1.setContentHuggingPriority(.required, for: .horizontal)
//label1.setContentCompressionResistancePriority(.required, for: .horizontal)
topologyView.addSubview(label1)
label1.leadingAnchor.constraint(equalTo: topologyView.leadingAnchor).isActive = true
label1.trailingAnchor.constraint(equalTo: topologyView.trailingAnchor).isActive = true
label1.bottomAnchor.constraint(equalTo: topologyView.bottomAnchor).isActive = true
label1.topAnchor.constraint(equalTo: topologyView.topAnchor).isActive = true
let window = UIWindow(frame: CGRect(x: 0, y: 0, width: 300, height: 350))
window.rootViewController = viewController
PlaygroundPage.current.liveView = window
PlaygroundPage.current.needsIndefiniteExecution = true
window.makeKeyAndVisible()
В результате (короткая метка):

или (длинная метка):

И ваш пример с двумя метками:
import UIKit
import Foundation
import PlaygroundSupport
let viewController = UIViewController()
viewController.view.backgroundColor = UIColor.green
let containerView = UIView()
containerView.backgroundColor = .gray
containerView.translatesAutoresizingMaskIntoConstraints = false
viewController.view.addSubview(containerView)
containerView.widthAnchor.constraint(equalToConstant: 200).isActive = true
containerView.heightAnchor.constraint(equalToConstant: 200).isActive = true
containerView.centerXAnchor.constraint(equalTo: viewController.view.centerXAnchor).isActive = true
containerView.centerYAnchor.constraint(equalTo: viewController.view.centerYAnchor).isActive = true
let topologyView = UIView()
topologyView.backgroundColor = .blue
topologyView.translatesAutoresizingMaskIntoConstraints = false
containerView.addSubview(topologyView)
let leadingConstraint = topologyView.leadingAnchor.constraint(greaterThanOrEqualTo: containerView.leadingAnchor)
// use default priority
//leadingConstraint.priority = .defaultLow
leadingConstraint.isActive = true
// use lessThanOrEqualTo
let trailingConstraint = topologyView.trailingAnchor.constraint(lessThanOrEqualTo: containerView.trailingAnchor)
// use default priority
//trailingConstraint.priority = .defaultLow
trailingConstraint.isActive = true
let topConstraint = topologyView.topAnchor.constraint(greaterThanOrEqualTo: containerView.topAnchor)
// use default priority
//topConstraint.priority = .defaultLow
topConstraint.isActive = true
// use lessThanOrEqualTo
let bottomConstraint = topologyView.bottomAnchor.constraint(lessThanOrEqualTo: containerView.bottomAnchor)
// use default priority
//bottomConstraint.priority = .defaultLow
bottomConstraint.isActive = true
topologyView.centerXAnchor.constraint(equalTo: containerView.centerXAnchor).isActive = true
topologyView.centerYAnchor.constraint(equalTo: containerView.centerYAnchor).isActive = true
let label1Title = "1234"
let label1 = UILabel()
label1.backgroundColor = .yellow
label1.translatesAutoresizingMaskIntoConstraints = false
label1.text = Array(repeating: label1Title, count: 10).joined()
// we can leave Hugging and Compression at default Priority
//label1.setContentHuggingPriority(.required, for: .horizontal)
//label1.setContentCompressionResistancePriority(.required, for: .horizontal)
topologyView.addSubview(label1)
label1.leadingAnchor.constraint(equalTo: topologyView.leadingAnchor).isActive = true
label1.trailingAnchor.constraint(equalTo: topologyView.trailingAnchor).isActive = true
label1.topAnchor.constraint(equalTo: topologyView.topAnchor).isActive = true
let label2 = UILabel()
label2.backgroundColor = .orange
label2.translatesAutoresizingMaskIntoConstraints = false
label2.text = "012345 ABCDE"
// we can leave Hugging and Compression at default Priority
//label2.setContentHuggingPriority(.required, for: .horizontal)
//label2.setContentCompressionResistancePriority(.required, for: .horizontal)
topologyView.addSubview(label2)
label2.leadingAnchor.constraint(equalTo: topologyView.leadingAnchor).isActive = true
label2.trailingAnchor.constraint(equalTo: topologyView.trailingAnchor).isActive = true
label2.bottomAnchor.constraint(equalTo: topologyView.bottomAnchor).isActive = true
label2.topAnchor.constraint(equalTo: label1.bottomAnchor).isActive = true
let window = UIWindow(frame: CGRect(x: 0, y: 0, width: 300, height: 350))
window.rootViewController = viewController
PlaygroundPage.current.liveView = window
PlaygroundPage.current.needsIndefiniteExecution = true
window.makeKeyAndVisible()
с короткой и длинной этикеткой:

