#ios #swift #uiview #autolayout
#iOS #swift #uiview #автоматическое описание
Вопрос:
У меня есть два UILabel
(вертикальное направление) в UIView
и UIButton
в одной «строке». Мне нужно получить этот результат:
Просматривает код инициализации:
private lazy var contentView: UIView = {
let view = UIView(frame: .zero)
view.translatesAutoresizingMaskIntoConstraints = false
return view
}()
private lazy var priceView: UIView = {
let view = UIView(frame: .zero)
view.translatesAutoresizingMaskIntoConstraints = false
view.setContentHuggingPriority(.required, for: .horizontal)
return view
}()
private lazy var priceLabel: UILabel = {
let label = UILabel(frame: .zero)
label.numberOfLines = 1
label.translatesAutoresizingMaskIntoConstraints = false
return label
}()
private lazy var oldPriceLabel: UILabel = {
let label = UILabel(frame: .zero)
label.numberOfLines = 1
label.translatesAutoresizingMaskIntoConstraints = false
return label
}()
private lazy var callButton: UIButton = {
let button = UIButton(frame: .zero)
button.translatesAutoresizingMaskIntoConstraints = false
button.layer.cornerRadius = 22.0
button.setTitleColor(.white, for: .normal)
button.setTitle("Call", for: .normal)
button.setContentHuggingPriority(.defaultLow, for: .horizontal)
button.setContentCompressionResistancePriority(.required, for: .horizontal)
return button
}()
Используя SnapKit, я создаю ограничения:
self.contentView.snp.makeConstraints { make in
make.top.bottom.equalToSuperview()
make.left.equalToSuperview().offset(16.0)
make.right.equalToSuperview().offset(-16.0)
}
self.priceView.snp.makeConstraints { make in
make.centerY.left.equalToSuperview()
make.right.equalTo(self.callButton.snp.left)
}
self.priceLabel.snp.makeConstraints { make in
make.left.equalToSuperview()
make.top.equalToSuperview()
make.right.lessThanOrEqualToSuperview()
}
self.oldPriceLabel.snp.makeConstraints { make in
make.left.bottom.equalToSuperview()
make.top.equalTo(self.priceLabel.snp.bottom).offset(8.0)
make.right.lessThanOrEqualToSuperview()
})
self.callButton.snp.makeConstraints { make in
make.left.equalTo(self.priceView.snp.right)
make.centerY.equalToSuperview()
make.height.equalTo(44.0)
make.right.equalToSuperview()
}
Я хочу priceView
уменьшить размер UILabels и callButton
растянуть на все свободное пространство. Сжатие и сжатие не работают, и я не понимаю, почему.
Комментарии:
1. Ограничения зависят от того, как вы хотели видеть одинаковый пользовательский интерфейс на устройствах разного размера. Пожалуйста, обновите вопрос.
2. размер не имеет значения. Высота фиксирована. Если ширина изменится, кнопка получит все свободное пространство.
3. Смотрите мой ответ, @AleksandrMaybach
4. Вы хотите, чтобы ваши метки или ваша кнопка имели фиксированную ширину? Например, если ваши «цены» равны
500
and600
, кнопка будет намного шире, чем если бы ваши цены были500 000 000
равны and999 999 999 999
.
Ответ №1:
Если вы не хотите использовать a UIStackView
, вы можете легко исправить свою проблему…
Для каждой метки измените:
make.right.lessThanOrEqualToSuperview()
Для:
make.right.equalToSuperview()
и это должно исправить.
Комментарии:
1. Да, я использовал это. Это работает, но почему??? если у меня есть два условия right = right, почему система автозапуска используется больше всего.
2. По умолчанию приоритет горизонтального охвата содержимого для a
UILabel
низкий (250), а сопротивление сжатию содержимого высокое (750). Таким образом, каждая метка будет расширяться, чтобы соответствовать своему тексту, И расширяться, чтобы придерживаться правого края своего супервизора (с этими ограничениями).
Ответ №2:
Во-первых, вам не нужно устанавливать translateAutoresizingMaskIntoConstraints
значение false в каждом из ваших представлений, поскольку вы устанавливаете их ограничения с помощью SnapKit.
Далее, лучший способ справиться с тем, что вы хотите, — это использовать назначение UIStackView
.
Это просто, как это:
self.view.addSubview(self.stackView_Main)
self.stackView_Main.snp.makeConstraints { (make) in
make.height.equalTo(44.0)
make.leading.trailing.equalToSuperview().inset(16.0)
make.top.equalToSuperview().inset(100.0)
}
self.callButton.snp.makeConstraints { (make) in
make.top.bottom.equalToSuperview()
}
И вы получите это отлично, без предупреждений:
Полный пример кода:
import SnapKit
import UIKit
class ViewController: UIViewController {
private lazy var stackView_Main: UIStackView = {
let stackView = UIStackView(arrangedSubviews: [self.stackView_Price, self.callButton])
stackView.axis = .horizontal
stackView.spacing = 5.0
stackView.alignment = .leading
stackView.distribution = .fill
return stackView
}()
private lazy var stackView_Price: UIStackView = {
let stackView = UIStackView(arrangedSubviews: [self.priceLabel, self.oldPriceLabel])
stackView.axis = .vertical
stackView.spacing = 5.0
return stackView
}()
private lazy var priceLabel: UILabel = {
let label = UILabel(frame: .zero)
label.numberOfLines = 1
label.text = "500 000 000"
return label
}()
private lazy var oldPriceLabel: UILabel = {
let label = UILabel(frame: .zero)
label.numberOfLines = 1
label.text = "999 999 999 999"
return label
}()
private lazy var callButton: UIButton = {
let button = UIButton(frame: .zero)
button.layer.cornerRadius = 22.0
button.backgroundColor = .black
button.setTitleColor(.white, for: .normal)
button.setTitle("Call", for: .normal)
button.setContentHuggingPriority(.defaultLow, for: .horizontal)
button.setContentCompressionResistancePriority(.required, for: .horizontal)
return button
}()
override func viewDidLoad() {
super.viewDidLoad()
self.view.addSubview(self.stackView_Main)
self.stackView_Main.snp.makeConstraints { (make) in
make.height.equalTo(44.0)
make.leading.trailing.equalToSuperview().inset(16.0)
make.top.equalToSuperview().inset(100.0)
}
self.callButton.snp.makeConstraints { (make) in
make.top.bottom.equalToSuperview()
}
}
}
Дайте мне знать, если это поможет 😉
Комментарии:
1. Я думал об
UIStackView
этом, и ваш ответ очень полезен, но возможно ли обойтись без этогоUIStackView
?2. Да, так и должно быть, но я думаю, вам нужно придать одной из сторон постоянную ширину, иначе вы можете увидеть некоторые предупреждения в своих журналах, а вы не всегда этого хотите. 🙂