#ios #autolayout
#iOS #автозапуск
Вопрос:
На основе документа Apple, systemLayoutSizeFitting
предполагается, что при возврате оптимального размера должны соблюдаться текущие ограничения на UIView
элемент. Однако всякий раз, когда я запускаю следующий код, я получаю {0, 0}
for UIView.layoutFittingCompressedSize
и {1000, 1000}
для UIView.layoutFittingExpandedSizeSize
ввода.
let mainView = UIView(frame: CGRect(origin: .zero, size: CGSize(width: 375, height: 50)))
mainView.backgroundColor = .red
PlaygroundPage.current.liveView = mainView
let subview = UIView()
subview.backgroundColor = .yellow
mainView.addSubview(subview)
subview.snp.makeConstraints { make in
make.width.equalToSuperview().dividedBy(3.0)
make.left.top.bottom.equalToSuperview()
}
mainView.setNeedsLayout()
mainView.layoutIfNeeded()
subview.frame
subview.systemLayoutSizeFitting(UIView.layoutFittingCompressedSize)
Я заметил, что если я изменю width
ограничение на что-то постоянное, то я получу действительное значение из systemLayoutSizeFitting
. Пытаюсь понять, почему происходит такое поведение и возможно ли получить правильное значение из systemLayoutSizeFittingSize(_ size: CGSize)
.
Ответ №1:
Документации по этому вопросу, похоже, не хватает.
Похоже, что .systemLayoutSizeFitting
это сильно зависит от .intrinsicContentSize
элемента. В случае UIView
у него нет внутреннего размера содержимого (если вы не переопределили его).
Итак, если связанное ограничение является процентом от другого ограничения, .systemLayoutSizeFitting(UIView.layoutFittingCompressedSize)
вернется {0, 0}
. Я полагаю, это связано с тем, что связанное ограничение может измениться (на ноль), поэтому минимальное значение фактически равно нулю.
Если вы измените свое .width
ограничение на константу (например, mainView.frame.width * 0.3333
), вы получите допустимое значение размера, поскольку ограничение постоянной ширины становится внутренней шириной.
Например, если ваш subview является UILabel
, этот элемент будет иметь собственный размер и .systemLayoutSizeFitting
должен возвращать значение размера, которое вы ожидаете.
Вот пример использования UILabel
, который продемонстрирует:
import UIKit
import PlaygroundSupport
let mainView = UIView(frame: CGRect(origin: .zero, size: CGSize(width: 375, height: 50)))
mainView.backgroundColor = .red
PlaygroundPage.current.liveView = mainView
let v = UILabel()
v.text = "Testing"
v.translatesAutoresizingMaskIntoConstraints = false
v.backgroundColor = .green
mainView.addSubview(v)
NSLayoutConstraint.activate([
v.widthAnchor.constraint(equalTo: mainView.widthAnchor, multiplier: 3.0 / 10.0),
v.leftAnchor.constraint(equalTo: mainView.leftAnchor),
v.topAnchor.constraint(equalTo: mainView.topAnchor),
v.bottomAnchor.constraint(equalTo: mainView.bottomAnchor),
])
mainView.setNeedsLayout()
mainView.layoutIfNeeded()
v.frame
v.systemLayoutSizeFitting(UIView.layoutFittingCompressedSize)
Комментарии:
1. Это полностью имеет смысл и согласуется с тем, что у меня также есть. Спасибо за подробное объяснение.