#ios #swift #autolayout #stackview
#iOS #swift #автозапуск #stackview
Вопрос:
Я пытаюсь использовать UIStackView с динамическим содержимым в своем проекте. Stackview привязан к началу и концу представления контейнера. Почему я закрепил это? Потому что в противном случае Xcode будет жаловаться, что я должен указать ширину или позицию X. Но, возможно, это неправильный подход — дайте мне знать. Представление стека в настоящее время настроено с:
- выравнивание: по центру (я тоже пробовал «Заполнять»)
- распределение: равный интервал
В любом случае, содержимое самого stackview создается из файла XIB, который расширяется в пользовательский UIView. Этот вид работает, но у меня возникает несколько проблем с макетом:
-
Когда в stackview всего несколько элементов, они распределены неравномерно. В идеале я хочу, чтобы UIView (оранжевая кнопка с зеленой областью) изменял размер как можно больше, чтобы заполнить эти пробелы
-
Когда в stackview много элементов, они в данный момент накладываются друг на друга. Это проблема. Размер отдельного пользовательского интерфейса должен быть изменен до наибольшего размера, чтобы они помещались горизонтально в UIStackView.
Что я сделал, чтобы добавить UIView (ы) в stackview, заключается в следующем:
labelStackView.arrangedSubviews.forEach { (view) in
view.removeFromSuperview()
}
for (index, character) in model.modelName.enumerated() {
// CharacterPlaceholder extends UIView
let characterPlaceHolder = CharacterPlaceholder()
...
labelStackView.addArrangedSubview(characterPlaceHolder)
}
в то время как CharacterPlaceholder примерно выглядит следующим образом
class CharacterPlaceholder: UIView {
override init(frame: CGRect) {
super.init(frame: frame)
customInit()
}
required init?(coder: NSCoder) {
super.init(coder: coder)
customInit()
}
private func customInit(){
let nib = UINib(nibName: "CharacterPlaceholder", bundle: nil)
if let view = nib.instantiate(withOwner: self, options: nil).first as? UIView {
addSubview(view)
view.frame = self.bounds
}
}
Я загрузил проект в свою учетную запись github:
https://github.com/alexwibowo/Flipcard
Есть идеи, что я сделал не так? Должен ли я фиксировать размер экрана в начале (или во время поворота экрана), а затем вручную вычислять ширину, необходимую для кнопок? Это кажется болезненным и очень ручным. Я надеюсь, что есть какая-то магия автозапуска, которую я могу здесь использовать.
Заранее благодарим вас за помощь!
Редактировать: я понимаю, что мне нужно использовать ‘fill equally’ для распределения, чтобы отдельные блоки букв имели одинаковый размер. Но также, чтобы они были ограничены доступным пространством stackview. Однако теперь они все еще могут перекрываться.
Комментарии:
1. Опубликованный вами ответ может решить вашу проблему, но, используя подобные вычисления, вы упускаете многое из того, что может сделать для вас автоматическая компоновка. Вы хотите, чтобы буквенные блоки в зеленом представлении были «выровнены по левому краю», как показано вверху? Или вы хотите, чтобы их размер заполнял ширину зеленого представления? Вы хотите, чтобы они оставались квадратными или растягивались в широкие прямоугольники?
Ответ №1:
Хорошо .. Я придумал, как это сделать. Во-первых, как я уже упоминал, мне нужно настроить распределение на «заполнение равномерно», чтобы каждое представление в stackview имело одинаковый размер. Но одного этого недостаточно. Мне нужно получить размер экрана. т. Е. через
view.frame.width
Затем, когда я разворачиваю файл xib, мне нужно вручную изменить его размер, используя простую математику. Например.:
let viewWidth = view.frame.width
let numberOfCharacters = model.modelName.count
let widthOfEach = Int(viewWidth) / numberOfCharacters
затем часть изменения размера:
characterPlaceHolder.widthConstraint.constant = widthOfEachIncludingMargin
Это widthConstraint — это выход, который я установил в представлении characterPlaceHolder.