2013-10-11 4 views
7

Я хочу иметь 6 объектов (кнопок), расположенных внутри одного вида. Они должны, однако, следовать некоторым ограничениям:Autolayout - равное распределение из 6 просмотров

enter image description here

  • Две верхние кнопки должны иметь одинаковое расстояние по вертикали от надтаблицы (A)
  • Два снизу - то же (C)
  • Два в центр должен иметь свои центры на центральной линии супервизора
  • Вертикальные расстояния между всеми кнопками (E) должны быть одинаковыми
  • и последнее, но не в последнюю очередь - кнопки должны быть квадратными (так ширина и высота должна быть такой же)
  • A = C
  • B = D

Можно ли этот эффект только в IB, или я должен использовать некоторый дополнительный код для ограничений?

+0

Я думаю, что это возможно в IB. Даже жестко я делаю все свои макеты в коде. Xcode не обрабатывает xibs хорошо. – dasdom

+0

Но - как вы устанавливаете ширину = ограничение по высоте и задаете для всех кнопок одинаковые значения? – kender

+0

[myView addConstraint: [Ограничение NSLayoutConstraint constraintWithItem: button: NSLayoutAttributeWidth relatedBy: NSLayoutRelationEqual toItem: атрибут кнопки: NSLayoutAttributeHeight multiplier: 1.0f constant: 0.0f]]; – dasdom

ответ

23

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

  1. Layout руководство: подхода, который не требует предопределяя любой интервал должен иметь UILayoutGuide объектов или, при использовании IOS версии до 9, только используйте скрытые виды, т. е. изображения с четким фоном или альфа нуль, между кнопками.

    Идея заключается в том, чтобы добавить эти направляющие макета с addLayoutGuide (или добавить невидимые взгляды с addSubview если поддерживает IOS версию хищничества IOS 9) между вашими шестью кнопками, как «распорка», и определить распорки быть тем же размером, каждый другие, и с ограничениями между распорками, надзором и кнопками, которые будут проходить между прокладкой. После того, как вы лежите, что из (показывая горизонтальные взгляды распорки в синем, вертикальных в красном, только так вы можете увидеть их):

    spacer views

    Эквивалента VFL для ограничений для этих красных UIView объектов, называемых vspacerX , будет:

     
    H:|[vspacer1][button1(100)][vspacer2(==vspacer1)][button2(==button1)][vspacer3(==vspacer1)]| 
    H:|[vspacer1][button3(==button1)][vspacer2][button4(==button1)][vspacer3]| 
    H:|[vspacer1][button5(==button1)][vspacer2][button6(==button1)][vspacer3]| 
    

    и ограничения на голубых UIView объектов, называется hspacerX, как:

     
    V:|[hspacer1][button1(100)][hspacer2(==hspacer1)][button3(==button1)][hspacer3(==hspacer1)][button5(==button1)][hspacer4(==hspacer1)]| 
    V:|[hspacer1][button2(==button1)][hspacer2][button4(==button1)][hspacer3][button6(==button1)][hspacer4]| 
    

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

    Во всяком случае, когда представление оказывается с этими направляющими компоновки (или невидимых представлений), он дает равномерно разнесенные кнопки следующим образом:

    spacers hidden

  2. Другой подход заключается в шести видов «контейнер», что будет выглядеть так:

    containers

    эквивалентного VFL для этих шесть контейнера UIView объектов могут выглядеть так:

     
    H:|[container1][container2(==container1)]| 
    H:|[container3(==container1)][container4(==container1)]| 
    H:|[container5(==container1)][container6(==container1)]| 
    
    V:|[container1][container3(==container1)][container5(==container1)]| 
    V:|[container2(==container1)][container4(==container1)][container6(==container1)]| 
    

    Вы можете добавить свои кнопки, которые, центрирование по одному на каждом из шести маленьких контейнеров, а затем сделать ваши контейнеры ясно:

    just buttons

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

  3. вид Stack: В перестановке предыдущего пункта, в прошивке 9, вы можете также использовать UIStackView, предназначенный именно для равномерно интервалов между видами. В этом случае поместите две кнопки каждый в три горизонтальных представления стека, а затем поместите эти представления стека в вертикальное представление стека. Это позволяет получить шесть одинаковых размеров контейнеров.

    См. WWDC 2015 video What's New in Cocoa Touch.

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

  4. NSLayoutAttributeCenterX с multiple: Другой метод предусматривает определение атрибутов attribute:NSLayoutAttributeCenterX и attribute:NSLayoutAttributeCenterY для шести кнопок, а не с помощью constant значения, используйте multiplier поле. Этот метод имеет небольшую простоту, но не всегда оказывает желаемый эффект, поэтому я не буду описывать его, если это то, что вы определенно хотите преследовать. Я уже ввел здесь территорию tl: dr.

  5. Вид коллекции: Другой подход заключается в использовании UICollectionView, который грамотно обрабатывает этот сценарий. Он хорошо разработан, чтобы позволить вам размещать ячейки в сетке.

  6. жестко прописывать значения: Для полноты картины отмечу, что вы могли бы просто указать конкретные значения для A, B, C и D (а также ширина и высота ограничения). Вам даже не нужно беспокоиться о настройке ограничений E, а просто установите ограничение по вертикали в середине два на их супервизор, и вы действительно сделали (потому что интервал, представленный E, должен быть естественным результатом предыдущие шаги, предполагая, что A = C и B = D).Если вы хотите отрегулировать эти значения на основе размера и/или ориентации устройства, вы можете реализовать viewWillLayoutSubviews для настройки констант для этих ограничений в соответствии с размером представления.

+0

Этот ответ является тщательным и удивительным! –

1

Обновление: У меня есть лучшее решение, которое не использует проставки. Проверьте это here.

Хорошо, это может быть достигнуто очень быстро в IB. Это так просто. Вот диаграмма, которая поможет проиллюстрировать. enter image description here

Предположите, что v1-6 - ваши кнопки, а s1-5 - ваши распорки. 1) в режиме управления IB перетащите все соединения, обозначенные красными линиями.

2) shift click v1-6 и значок булавки (выглядит как | -I- |) задает ширину и высоту определенному значению. также установите высоту и ширину равными.

3) сдвиг выберите s1-4 (не 5) и установите высоту равной. не дают ему определенной высоты, так как это должно быть рассчитано системой. вам также может потребоваться установить ширину s1-4 равным, но не дать им определенную ширину.

4) перетащите элемент управления из центра на передний и задний фронт и установите центральное ограничение.

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

enter image description here

Но когда я поворачиваю, упс!

enter image description here

Что здесь происходит? Проблема невероятно легко решить, когда мы поймем, что пошло не так. Мы хотим, чтобы IB не сокращала наши взгляды. Мы хотим, чтобы IB делала прокладки и пространства для сокращения и роста по мере необходимости, но чтобы оставить наши взгляды в покое. В основном, IB сократил прокладки вниз, насколько это возможно, в портрете и попытаться сделать все, что соответствует IB, сократило наши взгляды. Но мы хотели, чтобы IB сокращала вертикальные пространства между видами и променами, а не наши взгляды. Решение так просто. Все, что нам нужно сделать, это настроить приоритет вертикальных пространств, и все хорошо. Итак, выберите вертикальные пространства в IB и установите приоритет на 750. Линии вертикального интервала будут отображаться как пунктирные. Готово.

enter image description here

enter image description here

Ok, так что здесь все, как мы ожидали.

enter image description here

И с распорками дали понять:

enter image description here

enter image description here

Смежные вопросы