Я потратил два дня на то, чтобы опробовать различные решения для подходов Mixed и Pure Autolayout, чтобы достичь того, что было тривиальной настройкой scrollview до autolayout, и теперь это официально - я, должно быть, слишком глуп. Я настраиваю это в основном в раскадровке (ну, это просто так).
Итак, вот моя просьба о помощи.
Viewtree:
UIView
-UIView
-UIView
..-UIScrollview
...-UIButton
...-UIButton
...-UIButton
Кнопки должны прокручиваться горизонтально (слева направо и наоборот). Может кто-нибудь, пожалуйста, дайте мне знать, как установить ограничения для достижения этого с помощью чистого Autolayout ???
-
Я попробовал смешанный подход, вот так:
UIView
- UIView
- UIView
..-UIScrollview
...-UIView (contentview)
....-UIButton
....-UIButton
....-UIButton
... и установка фиксированной ширины и высоты ограничения для contentview
и translatesAutoresizingMaskIntoConstraints
настройки как на TechNote Apple. Кнопки и вид прокрутки настраиваются с использованием ограничений. Это приводит к прокрутке прокрутки (yay), но, увы, она прокручивается слишком далеко! Насколько я могу судить, ширина прокрутки как-то удваивается по сравнению с тем, что я установил для contentview ??? !!! ???
Я также пробовал использовать метод чистого размещения, как с, так contentview
и без. Все мнения есть translatesAutoresizingMaskIntoConstraints=NO
, кроме self.view
. Кнопки имеют фиксированные ограничения ширины / высоты и прикреплены ко всем четырем краям прокрутки. Ничего не прокручивается.
Так что я совершенно сбит с толку, почему не могу заставить его работать правильно. Любая помощь очень ценится, и если вам нужна другая информация, пожалуйста, обращайтесь!
ОБНОВЛЕНИЕ Снимок экрана с решением - ограничения buttonZ:
РЕДАКТИРОВАТЬ @ Джейми Форрест Таким образом, решение оказывается неправильным конечным ограничением для последней кнопки. Вместо 6441 значение, которое я установил, было отрицательным, -6441. Сложность в том, что при установке значения в раскадровке на панели инструментов «Pin» есть два параметра:
Текущее значение холста является отрицательным (приводит к отсутствию прокрутки), а параметр ниже является положительным (активация прокрутки). Это значит, что я не глупый, но, по крайней мере, полуслепой, наверное. Хотя, на мой взгляд, не беспокоит ли то, что XCode не показывает ошибку при «неправильной» настройке?
ВНОВЬ ИЗМЕНЕНО Теперь это забавно ... изменение конечного значения с -6441 (без прокрутки) на 6441 с прокруткой. Но мой старый друг, «слишком большой размер содержимого» вернулся, что привело к тому, что размер содержимого в два раза больше, чем должен быть! Чтобы получить правильную прокрутку содержимого, нужно было установить конечное ограничение на ZERO! Это неочевидно при работе в Storyboard, но, глядя на код @Infinity James, оно так и должно быть.
источник
contentSize
изUIScrollView
использования только автоматической компоновки. И именноcontentSize
это определяет, сколько вы можете прокрутить. Таким образом, вам придется установить это где-то вручную в конце концов. В остальном вы можете использовать ограничения макета для настройки рамок вида относительно друг друга.Ответы:
Трудно увидеть точные значения и настройки ваших ограничений, когда вы их вставили сюда, поэтому я не уверен, что посмотрю на ваши скриншоты, где вы ошиблись.
Вместо объяснения того, что не так в вашей настройке, я создал базовый пример проекта с очень похожей иерархией представления и настройкой ограничений, которую вы описали. Горизонтальная прокрутка работает, как и ожидалось, в примере проекта, который использует подход «Pure AutoLayout», который Apple описывает в Техническом примечании .
У меня также было много проблем с настройкой Auto Layout
UIScrollView
. Ключом к тому, чтобы заставить его работать, является уверенность в том, что все элементы в представлении прокрутки, взятые вместе, имеют ограничения, которые в конечном итоге связаны со всеми сторонами представления прокрутки и способствуют тому, чтобы система AutoLayout могла определять contentSize для представление прокрутки, которое будет больше, чем его рамка. Похоже, вы пытались сделать это в своем коде, но, возможно, у вас были некоторые лишние ограничения, которые делали contentSize слишком маленьким.Также следует отметить, что, как уже упоминалось, с AutoLayout и UIScrollview вы больше не устанавливаете contentSize явно. Система AutoLayout рассчитывает contentSize на основе ваших ограничений.
Я также нашел эту главу книги очень полезной, чтобы я понял, как все это работает. Надеюсь, все это поможет.
источник
LOL добро пожаловать в клуб глупости. Я один из основателей. : D
Для вертикальной прокрутки : единственный способ заставить его работать (iOS 8, Xcode 6 и чистая автопрокладка) - добавить следующие ограничения в мой вид прокрутки (все они связаны с суперпредставлением):
Моя структура:
Это конечный результат:
Это настройка:
Полноэкранный
Надеюсь, это спасет кого-то от ПОПЫТОК В 5 утра. : D
источник
Простой автономный пример
Судя по большому количеству голосов по вопросу и малому количеству голосов за ответы, люди не находят здесь понятного и быстрого решения. Позвольте мне попытаться добавить один. Этот проект является автономным примером, полностью выполненным в Интерфейсном Разработчике. Вы должны быть в состоянии пройти через это через 10 минут или меньше. Затем вы можете применить полученные вами концепции к своему собственному проекту.
Оригинальный вопрос спрашивает о кнопках прокрутки. Здесь я просто использую
UIView
s, но они могут представлять любой вид, который вам нравится. Я также выбрал горизонтальную прокрутку, потому что скриншоты раскадровки более компактны для этого формата. Однако принципы вертикальной прокрутки одинаковы.Ключевые идеи
UIScrollView
Следует использовать только один подвид. Это «UIView», который служит представлением содержимого для хранения всего, что вы хотите прокрутить.Начать новый проект
Это может быть только одно приложение.
Раскадровка
В этом примере мы сделаем горизонтальную прокрутку. Выберите View Controller и затем выберите Freeform в Инспекторе размера. Сделайте ширину
1,000
и высоту300
. Это просто дает нам место на раскадровке для добавления контента, который будет прокручиваться.Добавить представление прокрутки
Добавьте
UIScrollView
и прикрепите все четыре стороны к корневому виду контроллера представления.Добавить представление содержимого
Добавьте
UIView
как подпредставление к представлению прокрутки. Это ключ. Не пытайтесь добавить много подпредставлений в представление прокрутки. Просто добавьте одинUIView
. Это будет вашим представлением контента для других представлений, которые вы хотите прокрутить. Прикрепите представление содержимого к представлению прокрутки со всех четырех сторон.Равные высоты
Теперь в Outline документа, Commandщелкните и представление контента и родительское представление представления прокрутки , чтобы выбрать их обоих. Затем установите высоты равными ( Controlперетащите из представления содержимого в представление прокрутки). Это тоже ключ. Поскольку мы прокручиваем горизонтально, представление содержимого представления прокрутки не будет знать, насколько оно должно быть высоко, если мы не установим его таким образом.
Примечание:
Добавить содержание
Добавьте три
UIView
с и дайте им все ограничения. Я использовал 8-балльные поля для всего.Ограничения:
Установка ограничений ширины также является ключевой, чтобы представление прокрутки знало, насколько широко будет его представление содержимого.
Законченный
Вот и все. Вы можете запустить свой проект сейчас. Он должен вести себя как прокручиваемое изображение вверху этого ответа.
Для вертикальной прокрутки просто поменяйте местами все ширины и высоты в этом примере (проверено и работает).
Дальнейшее обучение
источник
ContentSize неявно устанавливается путем применения ограничений внутри UIScrollView.
Например, если у вас есть UIScrollView внутри UIView, это будет выглядеть так (как я уверен, вы знаете):
Это установит scrollView для заполнения размера containerView (таким образом, containerView должен быть определенного размера).
Затем вы можете настроить contentSize для UIScrollView, неявно установив его достаточно большим, чтобы удерживать кнопки следующим образом:
источник
Существует много вопросов об использовании AutoLayout с UIScrollView, ключевой момент, который мы игнорируем, заключается в том, что внутренние представления UIScrollView накладывают ограничения на представление содержимого, но не на сам UIScrollView. Обратитесь к Технической ноте TN2154 , вы можете найти:
На следующем рисунке изображено, что:
Вы можете найти конечный интервал, равный 500 точкам, если для UIScrollView наложено ограничение, представление будет неправильно размещено, и ему следует обновить свой фрейм. Однако никаких предупреждений и ошибок нет. Потому что все ограничения против представления контента.
UIScrollView рассчитает размер представления содержимого в соответствии с ограничениями внутренних представлений. (Например, размер контента: ширина = 100 (начальный пробел) + 200 (ширина представления) + 500 (задний пробел), высота = 131 (интервал сверху) + 200 (высота) + 269 (интервал снизу)
Как добавить ограничения для представлений в UIScrollView:
И все это сделано.
Простой способ справиться с AutoLayout с scrollview - добавить контейнерное представление, содержащее все подпредставления в представлении с прокруткой.
Вывод: ключевой момент для понимания AutoLayout с UIScrollView - это внутренние представления, накладывающие ограничения на представление содержимого, но не на сам UIScrollView.
прикрепленный пример кода
источник
Следующее решение работало для меня с scrollView с autolayout и без contentSize :
И вы сделали. Теперь вы можете добавить любое количество элементов управления в это представление и применить ограничения, относящиеся друг к другу (которые не работают без этого представления). Если вы не хотите использовать это представление, вам придется применять ограничения для каждого элемента управления, связанного с scrollView (не связанного друг с другом).
Подавляющий наконечник ..............
Critical . Допустим, для ясности UIScrollView имеет ширину 1000 и высоту 100. (На самом деле обычно эти значения будут динамическими, конечно, в зависимости от ширины устройства и т. Д. Но пока просто скажем 1000 в ширину и 100 в высоту.) Допустим, вы делаете горизонтальную прокрутку. Так что поместите UIView внутри UIScrollView. (Это «представление содержимого».) Установите все четыре ограничения представления содержимого сверху, снизу, впереди, сзади, в представление прокрутки. Сделайте их все ноль, даже если это кажется неправильным. Установите высоту содержимого UIView равным 100 и забудьте об этом. Теперь: вы хотите прокрутить горизонтально, поэтому установите ширину представления контента, скажем, 1225.
Обратите внимание, что ширина представления содержимого теперь на 225 больше ширины родительского представления прокрутки. Это нормально: на самом деле, вы ДОЛЖНЫ сделать это. Обратите внимание, что
... вы НЕ устанавливаете ширину трейлинга в минус 225 ...
Вы могли бы подумать, что должны «соответствовать» ширине, как обычно . Но если вы это сделаете, это не будет работать вообще.
Вы должны установить начальные и конечные числа в ZERO , никогда не отрицательные (даже если ширина "больше")
Интересно, что на самом деле вы можете установить начальные / конечные числа на любое положительное значение (попробуйте, скажем, «50»), и это дает вам некоторый запас отказов. (Это часто выглядит великолепно: попробуйте.) Любое отрицательное значение на любом конце будет "молча сломаться".
Обратите внимание, что, к сожалению, часто Xcode (по крайней мере, из 7.3.1),
«услужливо» установит для вас эти значения на отрицательные числа!
потому что он пытается автоматически подсчитать их для вас. Если это так, то он молча сломается Установите все четыре значения на ноль в первом случае. И установите ширину просмотра контента намного шире, чем «1000» в примере.
Отредактировано: я закончил с использованием UITableView вместо UIScrollView для большей части моих требований. Поскольку tableView мне кажется гораздо более гибким и динамичным.
источник
Я предполагаю, что у вас возникли проблемы с
contentSize
. Проверьте это сообщение в блоге о том , как обрабатыватьcontentSize
при использовании «чистого» AutoLayout подход. Суть в том, что ваши ограничения неявно определяют размер контента. Вы НИКОГДА не устанавливаете это явно при использовании AutoLayout. Я приложил пример проекта в конце поста блога, чтобы продемонстрировать, как он работаетисточник
В технических заметках есть часть, которую вы, возможно, просматривали. Вы можете неявно установить размер содержимого представления прокрутки, используя ограничения, прикрепленные к краям представления прокрутки.
Вот простой пример. Создайте раскадровку с одним представлением, у которого есть одно представление прокрутки. Установите ограничения вида прокрутки, чтобы он соответствовал размеру представления, в которое вы его поместили.
Внутри этого вида прокрутки добавить один вид. Явно установите размер этого представления, используя ограничения (и убедитесь, что размер больше, чем представление прокрутки).
Теперь добавьте еще четыре ограничения к этому внутреннему виду, фиксируя четыре ребра внутреннего вида к его родительскому виду прокрутки. Эти четыре ограничения приведут к тому, что размер контента увеличится, чтобы вместить внутренний вид.
Если у вас есть несколько представлений, которые вы хотите добавить в представление с прокруткой, например, горизонтально, вы бы заблокировали левую сторону первого подпредставления слева от представления прокрутки, закрепите подпредставления друг к другу по горизонтали и справа сторона последнего вспомогательного представления к правой стороне представления прокрутки. Эти ограничения заставят размер содержимого представления прокрутки расширяться для размещения всех подпредставлений и их ограничений.
источник
Если ваш вопрос «Как поместить кучу UITextFields в UIScrollView с вертикальной прокруткой так, чтобы они переместились с клавиатуры, когда они сфокусированы», лучший ответ:
Не.
Вместо этого используйте UITableViewController со статическими ячейками.
Вы получаете это бесплатное поведение прокрутки, И все вставки контента Просто работайте, если ваш контроллер представления отображается внутри UINavigationController.
источник
Вы должны организовать свой макет следующим образом:
ViewControllerView
содержитScrollView
,ScrollView
содержитContainerView
,ContainerView
содержит 2Labels
Затем выполните 3 шага для
ScrollView
прокрутки банокScrollView
штифт (верхний / правый / нижний / левый) дляViewControllerView
ContainerView
штифт (верхний / правый / нижний / левый) дляScrollView
Horizontally in Container
( не установитьVertically in Container
)Label1
прикрепить ( сверху / справа / слева) кContainerView
Label1
штифт (вправо / влево / снизу ) , чтобыContainerView
и сверху , чтобыLabel1
Надеюсь это поможет
источник
Подход с чистым автоматическим размещением работает прекрасно, но довольно сложно настроить его, если вы переходите с неавтоматического размещения. Я сделал это несколько раз, и у меня есть несколько общих советов:
источник
Спустя некоторое время, решив эту проблему, я наконец нашел решение. Я работаю с раскадровками универсальных размеров (600x600). Я создал UIView (contentView) размером с scrollView и создал ограничения для Top, Bottom, Leading и Trailing для scrollView. Затем я обрезал размер contentView вручную до 600x600. Раскадровка перестала пытаться изменить размер всего, и я смог работать, но на реальном устройстве или симуляторе вид выглядел ужасно. Я сделал 2 аутлета с ограничением размеров.
Тогда в viewDidLoad
Прекрасно работает.
источник
Я потратил несколько дней, пытаясь найти решение, как использовать AutoLayout view для встроенного Scrollview, чтобы центрировать scrollview на видимом экране, который работает на всех устройствах / размерах экрана, а также с поворотом экрана.
Я провел дни, пытаясь сделать это только с Autolayout, и приблизился, но никогда не был достаточно близко. В итоге мне пришлось добавить 3 строки кода на экран, в viewDidLoad.
Смотрите решение ниже:
Теперь перейдите к файлу .m и добавьте эти строки кода в viewDidLoad (поиграйтесь с количеством отступов, чтобы получить правильное центрирование вертикали)
{self.constraintVertVtoSV.constant = 150.0; }
теперь он должен работать на всех устройствах, быть правильно отцентрирован и по-прежнему правильно прокручиваться.
источник
Если, как и я, вы просто используете статический контент без ограничений внутри подпредставления, как вы можете сделать так:
источник
Подобная проблема у меня сегодня с iOS 8.4, Xcode 6.4
Есть представление, содержащее представление прокрутки, содержащее представление содержимого (UIView), содержащее подпредставления.
Все везде в авто макете. Края прокрутки скреплены с ребрами родительских видов с ограничениями. Края вида содержимого прикрепляются к краям вида прокрутки с ограничениями.
Первоначально представление содержимого будет отказываться от размера в качестве полной ширины представления прокрутки. Мне пришлось добавить дополнительное ограничение на представление содержимого, чтобы его ширина соответствовала представлению родительской прокрутки. Или я мог бы установить ограничение contentView.centerX == scrollView.centerX. Любой из них, в дополнение к закреплению краев, внезапно заставил представление контента иметь правильный размер.
Закрепление краев представления содержимого в представлении прокрутки с использованием визуальных ограничений формы,
Я использую процедуру для перебора массива и добавления их в scrollView.
источник
Я столкнулся с подобной проблемой. Я установил каждый ограниченный и всегда задавался вопросом, почему это все еще изменяет размеры некоторых подпредставлений. Моим решением было установить clipsToBounds в YES.
источник
В скором времени вы можете использовать это рабочее решение.
контрсилами
ScrollView
: Ведущий, трейлинг, верх, низ = супервизорContentView
: Leading, Trailing, Top, Bottom = ScrollView. Высота фиксированная / относительно содержимого.Вы можете установить ограничение ширины (contentView) равным суперпредставлению scrollviews, но выберите удалить удалить во время сборки, потому что вы будете добавлять это ограничение программно. Это просто, чтобы IB не жаловался на предупреждения.
А в View Controller
viewDidLayoutSubviews
я просто вызываю этот метод:источник
Я знаю, что это решение непрофессионала, а не то, что Apple предлагает в документе, но оно работало для меня дважды, с другим контентом и может быть настроено очень быстро: в контроллере представления раскадровки вставьте UIView. В UIView вставьте табличное представление, динамическое, 0 ячеек прототипа, стиль простой или сгруппированный. В табличном представлении вставьте представление прокрутки, в представлении прокрутки вставьте содержимое. Вот и все, нет настроек в контроллере пользовательского представления.
источник