AutoLayout: вертикальное центрирование двух UIView в супервиде, которые могут изменять размер

У меня есть два UIButton, один поверх другого, в супервидере, высота которого может быть изменена. Две кнопки должны иметь постоянный вертикальный интервал между ними, но верхнее и нижнее расстояние должны изменяться таким образом, чтобы две кнопки оставались центрированными в супервизии по мере изменения размера.

Я попытался создать два ограничения меньшего или равного (с равным приоритетом) на расстоянии до супервизора для каждой кнопки, а также постоянное вертикальное расстояние между кнопками, как показано ниже: enter image description here

(Причина, по которой это меньше или равно здесь, потому что это представление определено на заданной высоте в IB для 4-дюймовых экранов, но может быть сокращено для 3,5-дюймовых экранов.) Однако это не делает трюк, как вы можете видеть на скриншоте во время работы приложения: enter image description here

Это почти так, как если бы вы хотели сказать AutoLayout, что оба ограничения должны иметь равные значения, даже если оба они установлены как "меньше или равно". Есть ли способ сделать то, что я пытаюсь сделать, или, может быть, лучший способ?

Ответы

Ответ 1

Это так тривиально делать в IB.

1) ^ перетащить с кнопки1 на верх. выберите "центр по горизонтали в контейнере".

2) ^ перетащите из кнопки1 влево. выберите "центр вертикально в контейнере".

3) сделать то же самое с кнопкой2.

4) теперь осталось только размер кнопок, потому что это то, на что это похоже.

enter image description here

Это тоже очень тривиально.

5) ^ перетащите из кнопки 1 влево. выберите "ведущее пространство для поля контейнера".

6) ^ перетащите из кнопки 1 вправо. выберите "конечное пространство в поле контейнера".

7) сделать то же самое с кнопкой2.

Готовый продукт выглядит так (NB, я не совсем их центрировал, но мог бы быть достаточно лёгким):

enter image description here

enter image description here

Ответ 2

Простейшим способом вертикального центра является добавление ограничения NSLayoutAttributeCenterY - предпочтительно к элементу, который находится вблизи центра представления. И если все представления имеют ограничения по вертикальному расстоянию, тогда все они будут центрированы. Не нужно гадать с иерархией представлений или добавлять представления spacer.

[self.view addConstraint:
    [NSLayoutConstraint constraintWithItem:button2 
                                 attribute:NSLayoutAttributeCenterY
                                 relatedBy:NSLayoutRelationEqual 
                                    toItem:self.view 
                                 attribute:NSLayoutAttributeCenterY 
                                multiplier:1.0 
                                  constant:0]];

Если вам нужно настроить позиционирование, установите константу. Например: constant:-30 переместит его на 30 пунктов.

Вы также можете привязывать элементы на основе различных логических областей представления. Например, если вы хотите привязать свою первую кнопку к 25% высоты представления, вы можете установить множитель в 0.5.

Ответ 3

Согласился с rdelmar. Вот еще один вариант, если вы хотите сохранить иерархию просмотров.

В настоящее время вы используете кнопки сверху и снизу, используя ограничения. Вместо этого создайте два пустых UIView s, они будут использоваться в качестве разделителей. Они должны располагаться один сверху и один внизу ваших кнопок. Используя ограничения автоопределения, убедитесь, что высота этих двух распорных точек всегда одинакова. Убедитесь, что они прикреплены к верхней и нижней части кнопок, а также к верхней и нижней части надстройки соответственно.

В VFL: V:|-[spacer1(==spacer2)]-[button1]-(20)-[button2]-[spacer2(==spacer1)]-|.

Возможно, вам придется сделать это в коде, я не уверен, что IB может это сделать.

Ответ 4

Один из способов сделать это - приложить две кнопки в другом UIView и центрировать этот вид в представлении контроллера. Дайте кнопкам фиксированное расстояние до верхней и нижней части этого вида, а также фиксированное расстояние между ними или фиксированную высоту для представления.