как использовать UIScrollView в Построителе интерфейса?

пока я использовал UIScrollView успешно в прошлом, управляя им программно, у меня возникли проблемы с его работой, настроив его исключительно в Interface Builder.

у меня есть простая страница "о программе" в моем приложении для iPhone. У него есть UITextView, некоторые значки и ссылки на другие мои приложения. Я добавил Все эти взгляды к моему UIScrollView, расположив их так, чтобы их общий размер составлял > 480. Когда я запускаю свое приложение, scrollview отображает только содержимое, которое соответствует экран, и ничего не прокручивается.

можно ли сделать это полностью через IB, или я должен манипулировать contentSize с помощью кода?

17 ответов


вы забыли установить свойство contentSize UIScrollView. Как ни странно, вы не можете сделать это из Interface Builder. Вам придется сделать это с помощью контроллера вида, управляющего этим видом прокрутки.


ответ Boby_Wan заставил меня задуматься, и я нашел следующее решение для настройки contentSize UIScrollView из Interface Builder:

  1. выберите UIScrollView в раскадровке сцены
  2. перейти к инспектора удостоверение создать новый Пользовательский Атрибут Времени Выполнения (нажать кнопку+)
  3. изменить атрибут Ключ Пути to contentSize
  4. изменить атрибут тип to Size
  5. установка стоимостью to {желаемая ширина контента, желаемая высота контента}

например, установка значения {320, 920} позволит пользователю прокручивать весь дополнительный экран на iPhone.

(Я использую xcode 4.3.3, проект цель развертывания iOS is 5.1)

когда я впервые сделал это, я получил следующую ошибку:

Незаконным Конфигурация:
     Тип размера определяемые пользователем атрибуты среды выполнения с версиями Xcode до 4.3
     MainStoryboard.раскадровка

если вы тоже получите эту ошибку, ее легко исправить: выберите раскадровку в Проект Навигатор, и воспитывать файл инспектор. Найти / развернуть Документ Построителя Интерфейса раздел, и есть выпадающее меню для развитие. Гарантировать это установлено в Xcode 4.3


С Autolayout (iOS6+), вы можете избежать установки contentSize. Вместо этого установите следующие ограничения:

  1. закрепить верхнюю часть представление ScrollView на вершину топ-самых детей.
  2. и прикрепите дно к нижней части его нижней части-самого ребенка.

вы можете сделать это, используя только Interface Builder, перейдите к инспектору идентификации (вкладка третий инспектор) и добавьте новая пользовательская среда выполнения С

  • Ключ Пути: contentSize
  • тип: в размере
  • значение: {ширина, высота}

теперь есть способ сделать UIScrollView прокрутка без выхода раскадровка:

  1. выберите UIScrollView в раскадровке перейдите в раздел размер инспектор!--6-->, и дно значение (или любое другое значение вам нужно изменить) в Содержимое Врезки раздел на высоту области содержимого.
  2. теперь перейти к инспектора удостоверение и создать новый Пользовательская Среда Выполнения Атрибут (нажав кнопку+) и назовите его contentSize. Не важно что!--5-->тип или стоимостью вы заполняете (Вы даже можете оставить их значение по умолчанию).

это UIScrollView работать правильно, хотя я не знаю, почему второй шаг необходим (я узнал случайно). :(


один из подходов, который я использовал в прошлом, - это перетащить scrollview из содержащего его представления в interface builder и установить его фактический размер на то, что хочет contentSize.

что не очевидно в interface builder, так это то, что вы можете иметь несвязанные представления, которые хранятся в nib, но не являются частью основного представления, для которого предназначен nib.

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

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

во время выполнения, в - (void)viewDidLoad

scrollView.contentSize = scrollView.frame.size;
scrollView.frame = placeholder.frame;
[placeholder.superview addSubView:scrollView];
[placeholder removeFromSuperview];

альтернативно (если вы не использовали заполнитель):

CGRect f = self.view.frame;
scrollView.contentSize = f.size;
f.origin.x = 0;
f.origin.y = 0;
scrollView.frame = f;
[self.view addSubView:scrollView];

наконец, если вы "потеряете" свой вид прокрутки в interface builder (его можно закрыть, чтобы он исчез из сетки дизайна), не паникуйте. просто нажмите на него в списке объектов слева от сетки проектирования.


в Xcode 4.5 с помощью Autolayout у меня нет раздела вставок содержимого в моем инспекторе размеров. Поэтому мне пришлось добавить его в определенные пользователем атрибуты времени выполнения, а затем он работал нормально.

то, что вы добавляете в "пользовательские атрибуты времени выполнения", - это keyPath == contentInset, который имеет тип "Rect" (UIEdgeInsets, который имеет тот же вход, что и Rect) и определяется как {top, left}, {bottom, right}. ContentSize определяет только область окна scrollview. contentInset определяет прокручиваемый область.

Я надеюсь, что это поможет кому-то в той же ситуации.


многие из ответов выше вводят в заблуждение или устарели. С 2017 года (возможно, намного раньше) interface builder тут поддержка scrollviews с автоматически размером содержимого. Хитрость в том, что XCode дает особое, нестандартное значение ограничениям между scrollview и содержимым внутри него. Эти" внутренние " ограничения будут не фактически влияет на размер содержимого, как вы могли бы ожидать в противном случае.

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

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

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

я наткнулся на это случайно, а затем, увидев, как это, по-видимому, работает, привел меня к этой статье, которая полностью объясняет это и цитирует источник документов Apple для этого:

https://spin.atomicobject.com/2014/03/05/uiscrollview-autolayout-ios/

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


Если вы нажмете на значок свойств любого контроллера вида в Interface Builder, вы можете установить его в размер "Freeform" в смоделированных метриках и изменить размер основного вида, чтобы быть желаемым размером контента.

таким образом, вы можете создать содержимое ScrollView, как если бы это было одно большое представление. Поскольку это только смоделированная метрика, ваш контроллер вида будет изменен до границ окна при его загрузке.


настройка UIScrollView через Interface Builder не является интуитивно понятным. Вот мой контрольный список для его настройки:

  1. выберите XIB-файл UIViewController. В "Инспекторе удостоверений" построителя интерфейса измените UIView на тип класса UIScrollView

  2. В разделе "инспектор файлов" снимите флажок Autolayout

  3. В разделе "инспектор атрибутов" измените размер на Freeform. Затем можно растянуть вид прокрутки вручную или вы можете указать пользовательскую ширину и высоту в разделе "инспектор размеров".

  4. в" Identity Inspector "добавьте новый пользовательский атрибут среды выполнения" contentSize "типа" Size " и измените его на значение типа {320, 1000}. Вы больше не можете установить это программно, и поэтому этот шаг необходим, чтобы представление прокрутки знало, что содержимое представления прокрутки больше окна.


просто удалите автозапуск в scrollview. тогда код так прост:

scrollviewName.contentSize = CGSizeMake(0, 650);

просто создайте свойство iboulet .H файл затем синтезировать .m-файл. Убедитесь, что прокрутка включена.


да st3fan правильно, свойство contentSize UIScrollView должно быть установлено. Но для этого не следует отключать автозапуск. Вы легко можете настроить contentSize UIScrollView с autolayout только в IB, без какого-либо кода.

важно понимать, что при использовании autolayout contentSize UIScrollView не устанавливается напрямую, он рассчитывается на основе ограничений всех подвидов UIScrollView. И все, что вам нужно, это обеспечить надлежащие ограничения для подпанелей для обоих направлениях.

например. если у вас есть только один subview, вы можете установить его высоту и пространство сверху и снизу в superview (т. е. scrollView в нашем случае) contentSize.высота рассчитывается как сумма

Vertical Space (aSubview.top to Superview.top) + aSubview.height + Vertical Space (aSubview.top to Superview.top)

contentSize.ширина рассчитывается аналогично из горизонтальных ограничений.

Если слишком мало ограничений для вычисления contentSize правильно маленькая красная кнопка отображается рядом с элементом сцены контроллера вида, чтобы сообщить о неоднозначности макета.

Если существует много подвидов, то это может быть "цепочка" ограничений: сверху до самого верхнего подвида, высоты и пространства между подвидами и самым нижним подвидом снизу, как в Игры Danyal Айтекин ответ.

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

чтобы сделать scrollView прокручиваемым, вычисляемый contentSize должен быть больше размера scrollView.


вы можете иметь UIScrollView в раскадровке с Автомакета. В основном, что вам нужно:

  1. Добавить UIScrollView
  2. добавьте к нему все ограничения (например, вставки сверху, слева, справа, снизу)
  3. добавить "контейнер" UIView в UIScrollView
  4. если вы хотите только однонаправленную прокрутку (скажем, вертикальную): задайте высоту явно (например, 600) и ширину ссылки на ширину UIScrollView.
  5. если вы хотите двухнаправленная прокрутка просто устанавливает ширину и высоту.

storyboard setup


вот решение для разработки ScrollView с содержимым больше, чем экран полностью в раскадровке (ну, почти полностью, вам также нужно добавить 1 одну строку кода)

https://stackoverflow.com/a/19476991/1869369


Я узнаю более удобный способ.

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

2: Добавьте iboutlet вида прокрутки.

3: в viewDidLoad сохраните кадр.размер вида прокрутки.
(например, _scrollSize = _scrollView.рамка.размер;)

4: в viewWillAppear установите contentSize на CGSize, сохраненный ранее.
(например, _scrollView.contentSize = _scrollSize;)

5: сделано~


  1. Добавить UIViewController
  2. в Инспекторе атрибутов UIViewController - > сымитированные метрики " установить размер Freeform
  3. в Инспекторе размера UIViewController - > контроллер вида " установить высоту 800
  4. добавить UIScrollView в UIViewController
  5. добавьте все ограничения в UIScrollView (сверху, слева, справа, снизу) и добавьте выравнивание X = center
  6. добавить UIView в UIScrollView
  7. добавить все ограничения в UIView (сверху, слева, справа, внизу) и добавить выравнивание X = центр. Да, то же самое, что и для UIScrollView в #3, но для UIView
  8. добавить ограничение высоты в UIView. Например 780
  9. Run

Storyboard


создать новый проект Xcode

перейдите к Main.раскадровка файла

выберите ScrollView из библиотеки объектов.

установить рамку для ScrollView.

добавить другой вид для прокрутки и сохранить кадр такой же, как у ScrollView.

теперь, чтобы установить его высоту и ширину динамически, вы можете это настройка UIScrollView с помощью автоматической компоновки в XIB