autolayout - сделать высоту вида относительно половины высоты супервизора

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

Теперь я не могу понять, как это сделать. Вот что я получаю, когда пытаюсь настроить это:

Ограничение нижнего пространства установлено в "равно 284", что абсолютно и абсолютно бесполезно для меня, когда я перехожу на макет iPhone4, так как он сохраняет 284 точки пространства внизу экрана, и уменьшает вид, чтобы он не был больше половины размера экрана. И нет никакого способа установить это ограничение равным некоторой части высоты любого другого вида...

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

Может быть, я упускаю что-то очевидное?

Комментарии к вопросу (1)

Решение раскадровку, где вы можете установить точное соотношение между видами:

Сейчас:

Выгода!!!

P. S. Также обратите внимание, что этот метод работает с мнениями на разных уровнях вложенности и (очевидно) применяется для ширина

П. П. С. Иногда это может быть полезно, чтобы "реверс первого и второго пункта" из ограничения или установить обратный множитель (например 2 вместо 0,5) (но эти методы не полезно, если вы не'т понять, как эти взгляды соотносятся между собой).

Комментарии (5)
Решение

Теперь это возможно в IB, начиная с [по крайней мере] Xcode 5.1.1. Хотя мне потребовалось некоторое время, чтобы понять, что это на самом деле очень просто:

Сначала создайте базовое ограничение выравнивания сверху (вам также потребуется настроить ограничения снизу, слева и справа, как обычно) . Затем выберите ограничение и перейдите к инспектору Атрибуты:

Затем вы можете настроить множитель. Если вы хотите, чтобы он составлял 50% от супервида, оставьте значение 1, так как он будет выровнен по центру супервида. Это также отличный способ создания представлений с другими процентами (например, 25% от супервида).

Комментарии (6)

Потратив еще немного времени, я пришел к следующему.

Я отмечаю это как ответ, но он не очень удовлетворительный, так как предполагает, что вы не можете сделать это в Interface Builder, но правильное ограничение может быть добавлено в код после этого как:

- (void) viewWillAppear:(BOOL)animated
{

    NSLayoutConstraint *constraint = [NSLayoutConstraint constraintWithItem:upperview
                                                                 attribute:NSLayoutAttributeHeight 
                                                                 relatedBy:0 
                                                                    toItem:self.view
                                                                 attribute:NSLayoutAttributeHeight
                                                                multiplier:.5 
                                                                  constant:0];
    [self.view addConstraint:constraint];

}

По сути, оно устанавливает множитель 0.5 против высоты self.view, действуя на upperview. Мне пришлось установить приоритет нижнего ограничения вертикального пространства в IB ниже 1000, чтобы избежать кучи сообщений о нарушении ограничений.

Так что если кто-нибудь может показать, как это сделать в Interface Builder, это будет лучшим ответом на мой вопрос, в противном случае я полагаю, что это так же хорошо, как это получается (на данный момент)?

Комментарии (2)

Чуть проще и более прямолинейно, чем способ, чем Федор Волчек'ы ответ. -Нажмите и удерживайте кнопку управления и кнопку на панель. -Все еще удерживая кнопку, перетащите курсор в суперпанель нажмите на суперпанель. -Выбрать и"Формат" у.

-Нажмите кнопку инспекторе размера. -Затем дважды щелкните на ограничение.

-Убедитесь в том, что;quot; Высота &quot и; выбран для обоих элементов.

-Потом менять на "множитель" до 0.5 на половину экрана, или как часть суперпанель вы желаете.

Комментарии (1)

Есть и другая возможность в коде, если у вас есть два вида, которые должны иметь одинаковую высоту: просто установите высоту вида2 равной высоте вида1 (хитрость здесь заключается в том, чтобы не устанавливать высоту вида1 явно).

    [self.view addConstraints:[NSLayoutConstraint
        constraintsWithVisualFormat:@"V:[topLayoutGuide]-0-[_view1]-0-[_view2(==_view1)]-0-[bottomLayoutGuide]"
                            options:0
                            metrics:nil
                              views:viewsDict]];
Комментарии (2)

Свифт версию Мете'ы ответа:

    override func viewDidLoad() {
    super.viewDidLoad()
    // Do any additional setup after loading the view, typically from a nib.

    upperView.translatesAutoresizingMaskIntoConstraints = false

    var constraint = NSLayoutConstraint(item: upperView,
                                        attribute: NSLayoutAttribute.top,
                                        relatedBy: NSLayoutRelation.equal,
                                        toItem: self.view,
                                        attribute: NSLayoutAttribute.top,
                                        multiplier: 1,
                                        constant: 0)

    self.view.addConstraint(constraint)

    constraint = NSLayoutConstraint(item: upperView,
                                    attribute: NSLayoutAttribute.height,
                                    relatedBy: NSLayoutRelation.equal,
                                    toItem: self.view,
                                    attribute: NSLayoutAttribute.height,
                                    multiplier: 0.5,
                                    constant: 0)

    self.view.addConstraint(constraint)

    constraint = NSLayoutConstraint(item: upperView,
                                    attribute: NSLayoutAttribute.leading,
                                    relatedBy: NSLayoutRelation.equal,
                                    toItem: self.view,
                                    attribute: NSLayoutAttribute.leading,
                                    multiplier: 1,
                                    constant: 0)

    self.view.addConstraint(constraint)

    constraint = NSLayoutConstraint(item: upperView,
                                    attribute: NSLayoutAttribute.trailing,
                                    relatedBy: NSLayoutRelation.equal,
                                    toItem: self.view,
                                    attribute: NSLayoutAttribute.trailing,
                                    multiplier: 1,
                                    constant: 0)

    self.view.addConstraint(constraint)

}
Комментарии (0)