#swift #uistackview #layoutmargins
#swift #uistackview #layoutmargins
Вопрос:
Я хотел бы создать вертикальный stackview с 3 элементами в нем. Я хочу немного больше места только между 2-м и последним элементом. Итак, я подумал о добавлении к последнему элементу :
mylastelement.layoutMargins = UIEdgeInsets(top:30, left:0,bottom:0, right:0)
Но layoutmargins не применяются в моем stackview. Есть ли какой-либо простой способ добиться этого (я хотел бы избежать изменения внутренней высоты последнего элемента).
РЕДАКТИРОВАТЬ: я просто попытался увеличить высоту 2-го элемента ( 50) в пределах его фрейма, выполнив :
my2ndElementLabel.sizeToFit()
my2ndElementLabel.frame = CGRect(x:my2ndElementLabel.frame.origin.x,y:lmy2ndElementLabel.frame.origin.y,
width:my2ndElementLabel.frame.width, height:my2ndElementLabel.frame.height 50)
но это не имеет никакого эффекта.
РЕДАКТИРОВАНИЕ 2: Я попытался добавить случайное представление в свой UIStackView, но представление просто игнорируется! Возможно, вы что-то упустили в понимании того, как работает UIKit?… :
let v = UIView(frame:CGRect(x:0,y:0,width:100,height:400))
v.backgroundColor = .red
myStackView.addArrangedSubview(v)
//...
Комментарии:
1. Вы пробовали использовать ограничения автозапуска для верхнего привязки?
2. Что именно вы имеете в виду? На самом деле я мог бы ограничить каждый вид сверху вниз друг другом, но я хотел использовать stackview для обучения его использованию.
3. Странно, что нет способа добавить поле только к одному элементу Stackview. Похоже, что изменение фрейма представлений не имеет никакого эффекта
Ответ №1:
Вот расширение, которое я сделал, которое помогает быстро достичь таких полей :
extension UIStackView {
func addArrangedSubview(_ v:UIView, withMargin m:UIEdgeInsets )
{
let containerForMargin = UIView()
containerForMargin.addSubview(v)
v.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint.activate([
v.topAnchor.constraint(equalTo: containerForMargin.topAnchor, constant:m.top ),
v.bottomAnchor.constraint(equalTo: containerForMargin.bottomAnchor, constant: m.bottom ),
v.leftAnchor.constraint(equalTo: containerForMargin.leftAnchor, constant: m.left),
v.rightAnchor.constraint(equalTo: containerForMargin.rightAnchor, constant: m.right)
])
addArrangedSubview(containerForMargin)
}
}
Ответ №2:
Что вы могли бы сделать, так это установить пользовательский интервал между вторым и третьим элементом.
myStackView.setCustomSpacing(30.0, after: my2ndElementLabel)
Ответ №3:
В том же общем виде вы можете ограничить верхнюю (или нижнюю) привязку вашего представления относительно соответствующего края любого представления, в которое оно встроено. Что некрасиво, так это в некоторой степени дело вкуса, я нахожу ограничения автозапуска простыми в использовании и о них легко рассуждать.
Простой пример из Mac OS, а не iOS:
let button = ControlFactory.labeledButton("Filter")
addSubview(button)
button.bottomAnchor.constraint(equalTo: bottomAnchor, constant: -20).isActive = true
button.centerXAnchor.constraint(equalTo: centerXAnchor).isActive = true
Этот конкретный код находится в инициализаторе представления и позиционирует кнопку в середине представления, на 20 пунктов выше снизу.
Ответ №4:
Я обнаружил, что: похоже, UIStackView вообще не работает со старой системой определения размера (с .frame). Кажется, вам нужно ограничить высоту и ширину, а StackView будет ограничивать левое / верхнее / правое / нижнее положение для вас, когда вы добавляете arrangedSubview.
Моим вторым представлением была метка: я хотел, чтобы под текстом было поле в 40. Итак, я сначала вычислил высоту метки в ее свойстве .frame и ограничил высоту в frame.height 40 (= мое поле)
labelDesc.sizeToFit()
labelDesc.heightAnchor.constraint(equalToConstant:40).isActive = true
Хотя я нахожу свое собственное решение совершенно уродливым. Я уверен, что UIKit предоставляет лучший способ достижения такой простой цели, без необходимости создавать такого рода решения своими руками. Поэтому, пожалуйста, если вы привыкли работать с UIKit, скажите мне, есть ли какое-либо лучшее решение.
Ответ №5:
Рассмотрите возможность добавления «поля», вставив UIView правильного размера в представление стека по мере необходимости.
Если вам нужно расстояние в 40 пикселей между двумя конкретными элементами… добавьте UIView с ограничением высоты в 40 пикселей. Назначьте clearColor
фон, чтобы сделать его невидимым.
Вы можете добавить IBOutlets в это представление и скрыть его, как и любой другой элемент в представлении стека.