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


137

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

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

автопластинка блюз

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

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

Я упускаю что-то очевидное? ..


1
Я не думаю, что это уродливо, но умный трюк, позволяющий получить желаемое с помощью IB. Я сделал это, и когда вы используете правильные имена элементов, вы можете понять, что происходит. У вас даже может быть третий элемент в другой позиции или в центре, размер изменения зависит от этих двух вложенных представлений.
Jelle

Ответы:


169

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

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

Демонстрация шагов выше

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

Демонстрация второй ступени выше


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

@hqt, спасибо. Я думаю, что когда был написан принятый ответ, этот метод был недоступен. Иногда спрашивающие не возвращаются к старым вопросам или не заботятся об изменении принятого ответа. Но в конечном итоге я здесь, чтобы помочь, рада, что это помогло!
Firo

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

@Dean, ты должен убедиться, что First Itemэто View.Topне так View.Center Y. В противном случае да, он просто будет центрировать его. Вам также необходимо убедиться, что другие ограничения установлены правильно для обработки других краев вида.
Firo

1
View.Top равен Superview.Center Y множитель 1 не дает вам высоты. Это неполный ответ. Все, что вам нужно сделать, это подумать о том, что вы говорите, и вы увидите, что это дает вам линию через центр! Я бы отредактировал этот ответ, чтобы прояснить, о каких еще ограничениях вы говорите.
smileBot

185

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

Установить ограничение равенства высоты

Сейчас же:

Изменить множитель ограничения

ПРИБЫЛЬ !!!

Результат

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

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


1
Шаг 2, похоже, мне не подходит. Я не могу выбрать что-либо на панели, кроме переключения «Ограничение на поля». Я пытаюсь установить ширину UIImageView в UITableViewCell на 50% от представления содержимого.
DrMickeyLauer

2
ОБНОВЛЕНИЕ: очевидно, что построитель интерфейса не позволяет отображению содержимого быть явной целью любых ограничений автоматического макета. Мне нужно вставить фиктивное подпредставление в качестве дочернего элемента представления содержимого, чтобы это работало.
DrMickeyLauer

1
Меня устраивает. Вам нужно выбрать два представления в списке, а не на экране конструктора. для процентов разделите меньшее изображение на большее, чтобы получить значение множителя, например, меньшее изображение 25, большее изображение 135 - 25/135 = 0,185. Установите это как значение множителя, чтобы получить представление, что при x1 и x2 = 25, но увеличивается с увеличением 6 и 6 плюс и т. Д.
latenitecoder

1
Это сработало для меня, но обратите внимание, что мне также пришлось добавить три ограничения, которые устанавливают ограничения поля subview на 0. Спасибо
raddevus

Это должен быть принятый ответ. Сначала я пробую принятый ответ. Это не сработало, я прокрутил вниз, увидел этот ответ, и он сработал. Благодарность!
Mihir Oza

31

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

Я отмечаю это как ответ, но он не очень удовлетворительный, поскольку предполагает, что вы на самом деле не можете сделать это в 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, действуя на верхний вид. Мне пришлось установить приоритет ограничения нижнего вертикального пространства в IB ниже 1000, чтобы избежать кучи сообщений времени выполнения о нарушении ограничений.

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


3
Я думаю, это так хорошо, как сейчас. Было бы неплохо, если бы Apple предоставила нам доступ к значению множителя в IB, чтобы его можно было установить вместе с константой.
rdelmar

3
Для всех, кто смотрит на этот ответ, Xcode 5.1 теперь позволяет вам устанавливать множитель через Interface Builder. Теперь я могу настроить представления, которые на половину высоты своего супервизора, все через IB.
Марк Кренек

9

Немного проще и прямолинейнее, чем метод, чем ответ Федора Волчёка. -Удерживая кнопку управления, нажмите на подвид. -Удерживая нажатой кнопку команды, перетащите курсор на супервизор, затем нажмите на супервизор. -Выберите «Соотношение сторон».

введите описание изображения здесь

-Затем нажмите «Инспектор размеров». -Затем дважды щелкните ограничение. введите описание изображения здесь

-Убедитесь, что для обоих пунктов выбрана "высота". введите описание изображения здесь

-Затем измените "Multiplier" на 0,5 для половины экрана или любой другой части супервизора, которую вы хотите. введите описание изображения здесь


Легкий и быстрый подход! Спасибо, друг
Абдулла Саид

7

Есть еще одна возможность в коде, если у вас есть 2 представления, которые должны иметь одинаковую высоту: просто установите высоту view2 на высоту view1 (трюк здесь не в установке высоты view1 явно).

    [self.view addConstraints:[NSLayoutConstraint
        constraintsWithVisualFormat:@"V:[topLayoutGuide]-0-[_view1]-0-[_view2(==_view1)]-0-[bottomLayoutGuide]"
                            options:0
                            metrics:nil
                              views:viewsDict]];

Не понимал, что вы можете ссылаться на другие виды для такой ширины / высоты. Это самый чистый ответ, ИМО, если вы уже используете язык визуального формата.
Loeschg 05

Пример @brainray также объясняется здесь
alecs.popa

0

Быстрая версия ответа Мете:

    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)


}
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.