Как правильно настроить выравнивание для динамического UIStackView с внутренним XIB - PullRequest
0 голосов
/ 02 ноября 2018

Мой оригинал ViewController состоит только из одного scrollView, как это:

enter image description here

Теперь у меня также есть свой собственный xib файл (CheckBoxView), который в основном состоит из одной кнопки, см. Этот скриншот:

enter image description here

Я динамически создаю UIStackView s и добавляю их в ScrollView. Внутри этих UIStackView s я добавляю несколько экземпляров моего xib файла.

Чего я хочу добиться, так это чтобы StackViews были просто вертикально сложены. А внутри StackViews UIView s из моего xib-файла также должны быть вертикально сложены.

На данный момент это выглядит так: enter image description here

Таким образом, xib-Views не находятся в целом виде. Так как я использую multi-os-engine, я не могу предоставить код swift / obj-c. Но вот мой Java-код:

for (ItemConfiguration config : itemInstance.getConfigurations()) {

            List<DLRadioButton> radioButtons = new ArrayList<DLRadioButton>();

            UIStackView configView = UIStackView.alloc().initWithFrame(new CGRect(new CGPoint(0, barHeight), new CGSize(displayWidth, displayHeight - barHeight)));
            configView.setAxis(UILayoutConstraintAxis.Vertical);
            configView.setDistribution(UIStackViewDistribution.EqualSpacing);
            configView.setAlignment(UIStackViewAlignment.Center);
            configView.setSpacing(30);


            for (ConfigurationOption option : config.getOptions()) {
                UIView checkBox = instantiateFromNib("CheckBoxView");
                for (UIView v : checkBox.subviews()) {
                    if (v instanceof DLRadioButton) {
                        ((DLRadioButton) v).setTitleForState(option.getName(), UIControlState.Normal);
                        //((DLRadioButton) v).setIconSquare(true);
                        radioButtons.add((DLRadioButton) v);
                    }
                }
                configView.addArrangedSubview(checkBox);
            }
            // group radiobuttons
            //groupRadioButtons(radioButtons);

            configView.setTranslatesAutoresizingMaskIntoConstraints(false);
            scrollView().addSubview(configView);

            configView.centerXAnchor().constraintEqualToAnchor(scrollView().centerXAnchor()).setActive(true);
            configView.centerYAnchor().constraintEqualToAnchor(scrollView().centerYAnchor()).setActive(true);
        }


private UIView instantiateFromNib(String name) {
    return (UIView) UINib.nibWithNibNameBundle(name, null).instantiateWithOwnerOptions(null, null).firstObject();
}

Как мне нужно установить выравнивания и т. Д. Для достижения того, что я хочу. Это должно выглядеть так:

enter image description here

1 Ответ

0 голосов
/ 04 ноября 2018

Я не знаю, есть ли причина не использовать UITableView , что я настоятельно рекомендую для вашего случая. Если это невозможно, ниже вы можете найти несколько советов, которые должны помочь.


Если вы используете Auto Layout, вы должны установить ограничения для всех представлений, созданных в вашем коде. Ограничения должны быть исчерпывающими, чтобы iOS знала положение и размер каждого представления.

Снять избыточные ограничения

configView.centerXAnchor().constraintEqualToAnchor(scrollView().centerXAnchor()).setActive(true);
configView.centerYAnchor().constraintEqualToAnchor(scrollView().centerYAnchor()).setActive(true);

Эти два ограничения просто не имеют смысла для меня. Вам нужно, чтобы стековые представления были сложены внутри ScrollView, но не центрированы. Если я правильно понимаю вашу цель, это должно быть удалено

Установить ограничения ширины / x-позиции для UIStackViews

configView.setTranslatesAutoresizingMaskIntoConstraints(false);
scrollView().addSubview(configView);

Сразу после добавления стекового представления в ScrollView вам необходимо установить для него ограничения. Я предоставлю свой код в swift, но он выглядит очень похоже на то, что делает ваш Java-код, так что, надеюсь, вы сможете его без проблем перенести:

NSLayoutConstraint.activate([
  configView.leadingAnchor.constraintEqualToAnchor(scrollView.leadingAnchor),
  configView.trailingAnchor.constraintEqualToAnchor(scrollView.trailingAnchor)
]);

Установить ограничения по высоте для UIStackViews

StackViews не изменяет свой размер, когда вы добавляете в него упорядоченный вид. Так что вам нужно самостоятельно рассчитать желаемый размер стека и указать его явно через ограничения. Этого должно быть достаточно для размещения предметов и промежутков между ними. Я полагаю, что все предметы должны быть одинакового размера, пусть это будет 32 точки, тогда высота должна быть:

let stackViewHeight = items.count * 32 + stackView.space * (items.count + 1)

И установить новое ограничение высоты для стека:

configView.heightAnchor.constraint(equalToConstant: stackViewHeight).isActive = true

Установка y-позиции для UIStackView

Это немного более сложная часть, но наиболее важная для правильной работы представлений в представлении с прокруткой.

1) Измените цикл, чтобы узнать индекс UIStackView

Представление прокрутки всегда должно учитывать высоту своего содержимого, поэтому вам необходимо понять, какое представление стека является верхним, а какое - нижним. Чтобы сделать это, вам нужно изменить каждый цикл, который будет записан, как для цикла (;;):

for (int i = 0; i < itemInstance.getConfigurations().length; i++) {
  ItemConfiguration config = itemInstance.getConfigurations()[i]
  ...
}

Я не знаю, к какому типу относится ваш массив, поэтому, если у него нет функции индексирования, просто замените его соответствующим методом.

2) Установить верхнюю привязку для стековых представлений

Для первого представления стека в массиве верхний якорь должен быть равен верхнему якору представления прокрутки, для других это должен быть нижний якорь предыдущего представления стека + расстояние между ними (скажем, 8 точек в этом примере):

if i == 0 {
  configView.topAnchor.constraintEqualToAnchor(scrollView.topAnchor, constant: 8).isActive = true
} else {
  let previousConfigView = itemInstance.getConfigurations()[i - 1]
  configView.topAnchor.constraintEqualToAnchor(previousConfigView.bottomAnchor, constant: 8).isActive = true
}

3) Установить нижнюю привязку для последнего просмотра стека

Как уже было сказано - чтобы представление прокрутки знало о размере контента, нам нужно указать соответствующие ограничения:

if i == itemInstance.getConfigurations() - 1 {
  configView.bottomAnchor.constraintEqualToAnchor(scrollView.bottomAnchor, constant: 8).isActive = true
}

Примечание : учтите, что все ограничения должны быть установлены для видов, которые уже добавлены в вид прокрутки.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...