Авто макет делает мою жизнь трудной. Теоретически, это было бы действительно полезно, когда я перешел, но я, кажется, борюсь с этим все время.
Я сделал демонстрационный проект, чтобы попытаться найти помощь. Кто-нибудь знает, как сделать интервалы между представлениями увеличиваться или уменьшаться равномерно при изменении размера представления?
Вот три метки (вручную разнесены по вертикали):
Я хочу, чтобы они меняли размер интервала (а не размер изображения) равномерно, когда я поворачиваюсь. По умолчанию вид сверху и снизу смещается к центру:
Ответы:
Так что мой подход позволяет вам сделать это в конструкторе интерфейсов. То, что вы делаете, это создаете «разделительные виды», которые вы установили так, чтобы они одинаково соответствовали высотам. Затем добавьте верхние и нижние ограничения к меткам (см. Скриншот).
Более конкретно, у меня есть верхнее ограничение на «Spacer View 1» для суперпредставления с ограничением высоты с более низким приоритетом, чем 1000, и с высотой, равной всем другим «представлениям Spacer». «Spacer View 4» имеет ограничение по нижнему пространству для суперпредставления. Каждая метка имеет соответствующие верхние и нижние ограничения для своих ближайших «видов распорок».
Примечание: убедитесь, что у вас нет дополнительных верхних / нижних пространственных ограничений на ваших ярлыках для супервизора; только те, которые относятся к «космическим видам». Это будет удовлетворительным, так как верхнее и нижнее ограничения находятся в «Space View 1» и «Spacer View 4» соответственно.
Дух 1: Я продублировал свой взгляд и просто перевел его в ландшафтный режим, чтобы вы могли видеть, что это работает.
Дух 2: «Вид спейсера» мог бы быть прозрачным.
Дух 3: Этот подход может быть применен горизонтально.
источник
СМОТРИ, НЕ ПРОСТРАНСТВ!
Основываясь на предложениях в разделе комментариев моего первоначального ответа, особенно на полезных предложениях @ Rivera, я упростил свой первоначальный ответ.
Я использую картинки, чтобы проиллюстрировать, насколько это просто. Надеюсь, вы найдете гифки полезными. На случай, если у вас возникли проблемы с гифками, я включил старый ответ ниже с простыми снимками экрана.
Инструкции:
1) Добавьте свои кнопки или ярлыки. Я использую 3 кнопки.
2) Добавьте ограничение по центру от каждой кнопки в суперпредставление:
3) Добавьте ограничение для каждой кнопки в ограничение нижнего макета:
4) Настройте ограничение, добавленное в # 3 выше, следующим образом:
а) выберите ограничение, б) удалите константу (установите в 0), в) измените множитель следующим образом: возьмите количество кнопок + 1 и, начиная сверху, установите множитель как buttonCountPlus1: 1 , а затем buttonCountPlus1 : 2 и, наконец, buttonCountPlus1: 3 . (Я объясню, откуда я взял эту формулу в старом ответе ниже, если вам интересно).
5) Вот демо-ход!
Примечание. Если ваши кнопки имеют большую высоту, вам нужно будет компенсировать это постоянным значением, поскольку ограничение находится снизу кнопки.
Старый ответ
Несмотря на то, что говорится в документах Apple и в превосходной книге Эрики Садун (« Автоматическая разметка» ), можно равномерно распределять изображения без прокладок. Это очень просто сделать в IB и в коде для любого количества элементов, которые вы хотите разместить равномерно. Все, что вам нужно, это математическая формула, называемая «формула раздела». Это проще сделать, чем объяснить. Я сделаю все возможное, продемонстрировав это в IB, но это так же легко сделать в коде.
В рассматриваемом примере вы бы
1) начните с установки каждой метки, чтобы иметь ограничение по центру. Это очень просто сделать. Просто управляйте перетаскиванием от каждой метки вниз.
2) Удерживайте нажатой клавишу Shift, так как вы могли бы также добавить другое ограничение, которое мы будем использовать, а именно «руководство по разметке от нижнего пространства к нижнему».
3) Выберите «руководство по разметке от нижнего пространства до нижнего» и «центрировать горизонтально в контейнере». Сделайте это для всех 3 ярлыков.
По сути, если мы возьмем метку, координату которой мы хотим определить, и разделим ее на общее количество меток плюс 1, то у нас будет число, которое мы можем добавить в IB, чтобы получить динамическое местоположение. Я упрощаю формулу, но вы можете использовать ее для установки горизонтального интервала или как вертикального, так и горизонтального одновременно. Это супер мощный!
Вот наши множители.
Label1 = 1/4 = .25,
Label2 = 2/4 = .5,
Label3 = 3/4 = 0,75
(Правка: @Rivera прокомментировал, что вы можете просто использовать отношения прямо в поле множителя, а xCode с помощью math!)
4) Итак, давайте выберем Label1 и выберем нижнее ограничение. Как это:
5) Выберите «Второй элемент» в инспекторе атрибутов.
6) В раскрывающемся списке выберите «Поменять местами первый и второй элемент».
7) Обнулить константу и значение wC hAny. (Вы можете добавить смещение здесь, если вам это нужно).
8) Это критическая часть: в поле множителя добавьте наш первый множитель 0,25.
9) Пока вы это делаете, установите верхний «Первый элемент» на «CenterY», так как мы хотим центрировать его по центру y метки. Вот как все это должно выглядеть.
10) Повторите этот процесс для каждой метки и вставьте соответствующий множитель: 0,5 для метки 2 и 0,75 для метки 3. Вот конечный продукт во всех направлениях со всеми компактными устройствами! Супер просто. Я смотрел на множество решений, включающих множество кода и разделителей. Это, безусловно, лучшее решение, которое я видел по этому вопросу.
Обновление: @kraftydevil добавляет, что руководство по макету Bottom появляется только в раскадровках, а не в XIBS. Используйте «Нижнее пространство для контейнера» в XIBS. Хороший улов!
источник
Очень быстрое решение Interface Builder:
Для любого количества представлений, которые должны быть равномерно распределены в суперпредставлении, просто дайте каждому ограничение «Выровнять центр X по суперпредставлению» для горизонтальной компоновки или «Выровнять суперцентр по центру Y» для вертикальной компоновки и установите множитель равным
N:p
( ПРИМЕЧАНИЕ: некоторые повезло большеp:N
- см. ниже )где
N = total number of views
, иp = position of the view including spaces
Первая позиция - 1, затем пробел, следующая позиция - 3, поэтому p становится серией [1,3,5,7,9, ...]. Работает для любого количества просмотров.
Так что, если у вас есть 3 вида для разметки, это выглядит так:
РЕДАКТИРОВАТЬ Примечание: Выбор
N:p
илиp:N
зависит от порядка отношений вашего ограничения выравнивания. Если «Первый элемент» - это Superview.Center, вы можете использоватьp:N
, а если Superview.Center - «Второй элемент», вы можете использоватьN:p
. Если вы сомневаетесь, просто попробуйте оба ... :-)источник
Начиная с iOS 9, Apple сделала это очень легко с (долгожданным)
UIStackView
. Просто выберите представления, которые вы хотите содержать в Интерфейсном Разработчике, и выберите «Редактор» -> «Вставить» -> «Представление в стеке». Установите соответствующие ограничения ширины / высоты / поля для представления стека и убедитесь, что для свойства Distribution установлено значение «Равный интервал»:Конечно, если вам нужна поддержка iOS 8 или ниже, вам придется выбрать один из других вариантов.
источник
Я был на американских горках, любя автолайтинг и ненавидя его. Ключ к любви это, кажется, принять следующее:
Тем не менее, то, что вы пытаетесь сделать, не является простым и будет трудно достичь в конструкторе интерфейсов. Это довольно просто сделать в коде. Этот код
viewDidLoad
создает и размещает три метки так, как вы их запрашиваете:Как я уже сказал, этот код значительно упрощен благодаря нескольким методам категорий
UIView
, но для ясности я проделал длинный путь здесь.Категория здесь для тех, кто заинтересован, и у нее есть метод для равномерного распределения массива видов по определенной оси.
источник
Большинство из этих решений зависят от наличия нечетного количества элементов, чтобы вы могли взять средний элемент и отцентрировать его. Что если у вас есть четное количество предметов, которые вы хотите распределить равномерно? Вот более общее решение. Эта категория будет равномерно распределять любое количество элементов по вертикальной или горизонтальной оси.
Пример использования для вертикального распределения 4 меток в их суперпредставлении:
NSLayoutConstraint + EvenDistribution.h
NSLayoutConstraint + EvenDistribution.m
источник
Правильный и простой способ - использовать Stack Views.
источник
Проверьте библиотеку с открытым исходным кодом PureLayout . Он предлагает несколько методов API для распределения видов, в том числе варианты, в которых интервал между каждым видом фиксирован (размер вида изменяется по мере необходимости) и размер каждого вида фиксирован (интервал между представлениями изменяется по мере необходимости). Обратите внимание, что все это выполняется без использования каких-либо «видов спейсера».
Из NSArray + PureLayout.h :
Поскольку это все с открытым исходным кодом, если вам интересно посмотреть, как это достигается без разделительных представлений, просто взгляните на реализацию. (Это зависит от использования как
constant
иmultiplier
для ограничений.)источник
У меня похожая проблема и обнаружил этот пост. Однако ни один из предоставленных в настоящее время ответов не решает проблему так, как вы хотите. Они не делят интервал одинаково, а скорее равномерно распределяют центр меток. Важно понимать, что это не одно и то же. Я построил небольшую диаграмму, чтобы проиллюстрировать это.
Есть 3 вида, все 20pt в высоту. Использование любого из предложенных методов в равной степени распределяет центры видов и дает вам иллюстрированный макет. Обратите внимание, что y-центр представлений расположен на одинаковом расстоянии. Тем не менее, интервал между суперпредставлением и видом сверху составляет 15pt, а интервал между подпредставлениями - всего 5pt. Чтобы обеспечить одинаковое расстояние между видами, они должны быть 10pt, т.е. все синие стрелки должны быть 10pt.
Тем не менее, я еще не нашел хорошего общего решения. В настоящее время моя лучшая идея состоит в том, чтобы вставить «промежуточные виды» между подпредставлениями и установить равные высоты пространственных видов.
источник
Мне удалось решить это полностью в IB:
Поэтому, если у вас есть три метки, установите множители для каждого из этих ограничений на 0,1666667, 0,5, 0,833333.
источник
Я нашел идеальный и простой метод. Автоматическая разметка не позволяет вам изменять размеры пространств одинаково, но она позволяет вам изменять размеры представлений одинаково. Просто поместите несколько невидимых видов между вашими полями и сообщите авторазметке, чтобы они оставались одинаковыми по размеру. Работает отлично!
Однако следует отметить одну вещь; когда я уменьшал размер в конструкторе интерфейса, иногда он путался и оставлял метку там, где она была, и возникал конфликт, если размер изменялся нечетным образом. В противном случае это работало отлично.
редактировать: я обнаружил, что конфликт стал проблемой. Из-за этого я взял одно из интервальных ограничений, удалил его и заменил двумя ограничениями: больше или равно или меньше или равно. Оба были одинакового размера и имели гораздо более низкий приоритет, чем другие ограничения. Результатом не стало дальнейшего конфликта.
источник
Основываясь на ответе Бена Долмана, это распределяет взгляды более равномерно (с отступами и т. Д.):
источник
проверьте https://developer.apple.com/library/ios/documentation/UserExperience/Conceptual/AutolayoutPG/AutoLayoutbyExample/AutoLayoutbyExample.html хорошее описание решения вашей проблемы.
источник
С ярлыками это работает нормально, по крайней мере:
@"H:|-15-[first(==second)]-[second(==third)]-[third(==first)]-15-|
Если первый имеет такую же ширину, как второй, а второй третий и третий первый, то все они получат одинаковую ширину ... Вы можете сделать это как по горизонтали (H), так и по вертикали (V).
источник
версия swift 3
источник
Я знаю, что прошло много времени с момента первого ответа, но я столкнулся с той же самой проблемой и хочу поделиться своим решением. Для будущих поколений ...
Я установил свои взгляды на viewDidLoad:
А затем в updateViewConstrains сначала я удаляю все ограничения, затем создаю словарь представлений и затем вычисляю пространство, которое будет использоваться между представлениями. После этого я просто использую Visual Language Format, чтобы установить ограничения:
Хорошая вещь об этом методе - то, что вы должны делать очень мало математики. Я не говорю, что это идеальное решение, но я работаю для макета, который я пытался достичь.
Я надеюсь, что это помогает.
источник
Вот решение, которое будет вертикально центрировать любое количество подпредставлений, даже если они имеют уникальные размеры. То, что вы хотите сделать, это создать контейнер среднего уровня, центрировать его в суперпредставлении, затем поместить все подпредставления в контейнер и расположить их относительно друг друга. Но, что очень важно, вам также необходимо ограничить их верх и низ контейнера, чтобы контейнер мог быть правильно подобран по размеру и центрирован в суперпредставлении. Определив правильную высоту из своих подпредставлений, контейнер может быть центрирован по вертикали.
В этом примере
self
это суперпредставление, в котором вы центрируете все подпредставления.источник
Я только что решил свою проблему, используя функцию умножения. Я не уверен, что это работает для всех случаев, но для меня это работало отлично. Я на Xcode 6.3 FYI.
То, что я закончил, было:
1) Сначала расположение кнопок на экране шириной 320px распределялось так, как я хотел, чтобы это выглядело на устройстве 320px.
2) Затем я добавил ведущее ограничение пространства для суперпредставления на всех моих кнопках.
3) Затем я изменил свойства начального пространства так, чтобы константа была 0, а множитель - это смещение по x, деленное на ширину экрана (например, моя первая кнопка была на 8 пикселей от левого края, поэтому я установил свой множитель на 8/320)
4) Тогда важным шагом здесь является изменение второго элемента в отношении ограничений на superview.Trailing вместо superview.leading. Это имеет ключевое значение, потому что superview.Leading равно 0, а трейлинг в моем случае равен 320, поэтому 8/320 - это 8 пикселей на устройстве 320px, затем, когда ширина суперпредставления изменяется на 640 или что-то еще, все представления перемещаются в соотношении относительно ширины. размером экрана 320 пикселей. Математика здесь намного проще для понимания.
источник
Многие ответы не верны, но получают много очков. Здесь я просто пишу решение программно, три вида выровнены по горизонтали, без использования разделительных видов , но это работает только тогда, когда известны ширины меток при использовании в раскадровке .
источник
Вот еще один ответ. Я отвечал на аналогичный вопрос и увидел ссылку на этот вопрос. Я не видел ни одного ответа, похожего на мой. Итак, я подумал написать это здесь.
И снова, это может быть сделано довольно легко с iOS9 UIStackViews также.
Обратите внимание, что это точно такой же подход, как указано выше. Он добавляет четыре вида контейнера, которые заполнены одинаково, и вид добавляется к каждому виду стека, который выровнен по центру. Но эта версия UIStackView уменьшает объем кода и выглядит красиво.
источник
Другой подход может заключаться в том, чтобы верхняя и нижняя метки имели ограничения относительно вида сверху и снизу соответственно, а средний вид имел ограничения сверху и снизу относительно первого и третьего вида соответственно.
Обратите внимание, что у вас больше контроля над ограничениями, чем может показаться, перетаскивая представления близко друг к другу, пока не появятся направляющие пунктирные линии - они указывают на ограничения между двумя объектами, которые будут сформированы, а не между объектом и суперпредставлением.
В этом случае вы захотите изменить ограничения на «Больше или равно» желаемому значению вместо «равно», чтобы позволить им изменить размер. Не уверен, что это будет делать именно то, что вы хотите.
источник
Очень простой способ решить эту проблему в InterfaceBuilder:
Установите метку по центру (label2) на «Горизонтальный центр в контейнере» и «Вертикальный центр в контейнере»
Выберите центрированную метку и верхнюю метку (label1 + label2) и добавьте ДВА ограничения для вертикального интервала. Один с большим или равным минимальному интервалу. Один с меньшим или равным максимальному интервалу.
То же самое для метки по центру и нижней метки (label2 + label3).
Кроме того, вы можете также добавить два ограничения для label1 - верхнее пространство для SuperView и два ограничения для label2 - нижнее пространство для SuperView.
В результате все 4 расстояния изменят свои размеры в равной степени.
источник
Я сделал функцию, которая может помочь. Этот пример использования:
будет вызывать это вертикальное распределение (извините, у вас нет 10 репутации для встраивания изображений) И если вы измените ось и некоторые значения полей:
Вы получите это горизонтальное распределение .
Я новичок в iOS, но вуаля!
EvenDistribution.h
EvenDistribution.m
источник
Да, вы можете сделать это исключительно в конструкторе интерфейсов и без написания кода - единственное предостережение в том, что вы изменяете размер метки, а не распределяете пробелы. В этом случае совместите метки X и Y с суперпредставлением, чтобы оно было зафиксировано в центре. Затем установите вертикальное пространство метки 1 для суперпредставления и метку 2 для стандарта, повторите для метки 3. После установки метки 2 самый простой способ установить метки 1 и 3 - изменить их размер, пока они не защелкнутся.
Вот горизонтальный дисплей, обратите внимание, что вертикальное пространство между меткой 1 и 2 установлено стандартным:
А вот портретная версия:
Я понимаю, что они не на 100% равномерно распределены между базовыми линиями из-за разницы между стандартным пространством между метками и стандартным пространством для суперпредставления. Если это вас беспокоит, установите размер 0 вместо стандартного
источник
Я установил значение ширины только для первого элемента (> = ширина) и минимальное расстояние между каждым элементом (> = расстояние). Затем я использую Ctrl для перетаскивания второго, третьего ... элемента на первый, чтобы связать зависимости между элементами.
источник
Поздно до вечеринки, но у меня есть рабочее решение для создания меню горизонтально с интервалом. Это можно легко сделать используя
==
NSLayoutConstraintисточник
В Android есть метод объединения видов в систему на основе ограничений, которую я хотел имитировать. Поиски привели меня сюда, но ни один из ответов не сработал. Я не хотел использовать StackViews, потому что они имеют тенденцию вызывать у меня больше горя в будущем, чем экономить сразу. Я закончил тем, что создал решение, которое использовало UILayoutGuides, помещенное между представлениями. Управление их шириной позволяет использовать различные типы дистрибутивов, стили цепочек на языке Android. Функция принимает начальный и конечный якорь вместо родительского представления. Это позволяет размещать цепочку между двумя произвольными представлениями, а не распределять внутри родительского представления. Он использует,
UILayoutGuide
который доступен только в iOS 9+, но это больше не должно быть проблемой.источник
Я хотел выровнять 5 изображений по горизонтали, поэтому в итоге последовал ответ Мете с небольшой разницей.
Первое изображение будет центрировано по горизонтали в контейнере, равном 0 и множителю 1: 5:
Второе изображение будет центрировано горизонтально в контейнере, равном 0, и множителе 3: 5:
И так для остальных изображений. Например, пятое (и последнее) изображение будет горизонтально отцентрировано в контейнере, равном 0, и множителе 9: 5:
Как объяснил Мете, порядок идет 1, 3, 5, 7, 9 и т. Д. Позиции следуют той же логике: первая позиция - 1, затем пробел, затем следующая позиция 3 и т. Д.
источник
Почему бы вам просто не создать TableView и сделать
isScrollEnabled = false
источник