Как использовать UIScrollView в раскадровке

125

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

Алекс Рейнольдс
источник
1
Привет всем, пожалуйста, смотрите комментарии ниже, чтобы узнать о новых способах сделать это. Я написал это 2 года назад, и xCode сильно изменился. Есть и другие способы сделать это сейчас, так что имейте в виду. Решения для iOS 7 и iOS 8, предложенные в комментариях,
Алекс Рейнольдс,
Вот и я снова 2 года спустя все еще получаю комментарии о том, что это не работает или что автопластинка лучше. Изначально вопрос был в том, как это сделать в ios 5/6. В наши дни я использую для этого только автоматическую раскладку, так что вы должны / можете тоже. См. Ответы на вопросы об автоперемещении. Пожалуйста, проголосуйте за ответы с автоматическим раскладом, если они полезны. Спасибо всем
Алекс Рейнольдс

Ответы:

149

Я отвечаю на свой вопрос, потому что я потратил 2 часа, чтобы найти решение, а StackOverflow позволяет использовать этот стиль QA.

От начала до конца вот как заставить его работать в раскадровке.

1: перейдите к просмотру контроллера и нажмите Attribute Inspector.

2: измените размер на Freeform«Предполагаемый».

3: перейдите к основному представлению на этой раскадровке, а не к просмотру прокрутки, а к представлению верхнего уровня.

4: Щелкните Size Inspectorи установите желаемый размер этого вида. Я изменил свой рост на 1000.

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

5: Перетащите на прокрутку и растяните ее так, чтобы она занимала весь вид. Теперь у вас должно быть scrollview размером 320,1000, сидящее на представлении в вашем контроллере представления.

Теперь нам нужно заставить его прокручиваться и правильно отображать контент.

6: Нажмите на свою прокрутку и нажмите Identity Inspector.

7: Добавьте User Defined runtime attributeс KeyPath, contentSizeзатем введите РАЗМЕР и введите размер вашего контента. Для меня это (320, 1000).

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

8: Добавьте runtime attributeKeyPath frameс типом RECT и 0,0,320,416.

Теперь, когда мы запустим наше приложение, у нас будет видимая прокрутка с рамкой 0,0,320, 416 и с возможностью прокрутки до 1000. Мы можем размещать наши подвиды, изображения и многое другое в раскадровке так, как мы хотим, чтобы они отображались. Затем наши атрибуты времени выполнения обязательно отображают его правильно. И все это без единой строчки кода.

Алекс Рейнольдс
источник
5
Если вы правильно используете функцию автоматического изменения размера scrollview, вам не нужно определять frameатрибут. Действительно, не все устройства имеют одинаковый размер (iPhone 5).
Tronix117,
Tronix117, тогда как решить эту проблему без этого атрибута?
Андрас Хатвани
2
Если у вас есть решение для iOS 7, дайте мне знать. Этот ответ был опубликован более года назад, до выхода iOS 7. Я завалился, иначе я бы обновил его для iPhone5 и ios7
Алекс Рейнольдс
2
ПРИМЕЧАНИЕ. Решение для iOS7 находится ниже stackoverflow.com/a/22489795/1553014
Раджа Рао
1
Примечание. Для iOS 8.3 XCode 6.3 ответ здесь: stackoverflow.com/questions/26742230/…
T.Coutlakis
51

Вот шаги, Auto Layoutкоторые у меня сработали в XCode 8.2.1.

  1. Выберите Size Inspectorиз View Controller, и изменения Simulated Sizeк Freeformс высотой 1000 вместо Fixed.
  2. Переименуйте представление View Controllerкак RootView .
  3. Перетащите Scroll Viewкак subview RootView и переименуйте его как ScrollView .
  4. Добавьте ограничения для ScrollView :
    • ScrollView [Top, Bottom, Leading, Trailing] = RootView [Top, Bottom, Leading, Trailing]
  5. Перетащите Vertical Stack Viewкак подвид ScrollView и переименуйте его как ContentView .
  6. Добавьте ограничения для ContentView :
    • ContentView .height = 1000
    • ContentView [Top, Bottom, Leading, Trailing, Width] = ScrollView [Top, Bottom, Leading, Trailing, Width]
  7. Выберите Attributes Inspectorиз ContentView , и изменить Distributionк Fill Equallyвместо Fill.
  8. Перетащите Viewкак subview ContentView и переименуйте его как RedView .
  9. Установить Redв качестве фона RedView .
  10. Перетащите Viewкак subview ContentView и переименуйте его как BlueView .
  11. Установить Blueв качестве фона BlueView .
  12. Выберите RootView и нажмите Update Framesкнопку.
    • Update Framesэто новая кнопка в Xcode8 вместо Resolve Auto Layout Issuesкнопки. Похоже на кнопку обновления, расположенную на панели управления под раскадровкой: Кнопка обновления кадров

Просмотр иерархии:

  • RootView
    • ScrollView
      • ContentView
        • RedView
        • BlueView

Просмотр сцены контроллера (высота: 1000):

место действия

Запускаем на iPhone7 (Высота: 1334/2):

демонстрация

jqgsninimo
источник
У меня такая же проблема, и мне интересно, будет ли это работать, если размер моей прокрутки не соответствует размеру rootview?
GalaxyVintage
Но дело в том, что внизу будет пустое место для ipad
Г.Абхисек
Примечание для установки BlueView«сверху s до RedView» дна s для начинающих , как я (Xcode 8.2): 1) Перетащите BlueView ниже RedView (т.е. они не должны перекрываться или шаг 4) не будет работать). 2) Откройте меню контактов внизу. 3) Щелкните маленькую стрелку справа от ограничения верхнего поля. 4) Выберите в RedViewэтом меню и установите значение 0. Это отличается от предыдущих версий Xcode, в которых вы могли делать такие вещи, как Editor-> Pin-> ...
Krøllebølle
просто любопытно, почему вы используете вертикальное представление стека вместо обычного UIView?
Changerrs
@Changerrs я использую, UIStackViewчтобы избежать проблем с установкой ограничений.
jqgsninimo
43

Вот шаги, которые у меня сработали на iOS 7 и XCode 5.

  1. Перетащите ViewController (он поставляется с UIView «View»).

    1.1 Выберите «Контроллер просмотра», затем выберите «Инспектор файлов» и снимите флажок «Автоматическая компоновка».

  2. Перетащите ScrollView (как дочерний элемент ViewController's UIView "View")
  3. Выберите ScrollView и откройте «Инспектор идентичности».
  4. В поле keyPath введите contentSize. Выберите «Размер» в поле «Тип». И введите {320, 1000} в качестве значения.

    Примечание. Шаг 4 просто говорит, что скроллер содержит некоторый контент размером 320x1000 единиц. Таким образом, установка contentSize заставит скроллер работать.

  5. Выберите View Controller, выберите «Attributes Inspector», затем выберите Freeform from Size.

    Примечание: шаг 5 позволит нам изменить размер «представления», с которым поставляется контроллер представления.

  6. Выберите «Просмотр», а затем «Инспектор размеров».

  7. Установите ширину на 320 и высоту на 1000.

Примечание. 5, 6 и 7 предназначены исключительно для того, чтобы мы могли видеть растянутый или весь развернутый вид внутри StoryBoard. Примечание. Обязательно снимите флажок «Auto Layout» в View Controller.

Ваша иерархия представления должна выглядеть так: иерархия

Раджа Рао
источник
3
Этот метод все еще работает с Xcode 6.1 и iOS 8.1.
Крис Харрис,
1
Удивительный. Спасибо за это. Определенно работает на Xcode 6.1 и iOS 8.1, как уже упоминалось.
Шанкер Каура
45
Хорошо ... а что, если нам НУЖНА автоматическая раскладка?
PostCodeism
1
Мач лучше ответь .. Спасибо!
StefMa
1
Решение для класса автоматической компоновки и размера iOS 8 stackoverflow.com/questions/26742230/…
jithin
13

После нескольких часов проб и ошибок я нашел очень простой способ поместить содержимое в прокрутки, которые находятся «вне экрана». Протестировано с XCode 5 и iOS 7. Вы можете сделать это почти полностью в Storyboard, используя 2 небольших приема / обходных пути:

  1. Перетащите viewcontroller на раскадровку.
  2. Перетащите scrollView на этот viewController, для демонстрации вы можете оставить его размер по умолчанию, охватывающий весь экран.
  3. Теперь приходит трюк 1 : перед добавлением любого элемента в scrollView перетащите его в обычное «представление» (это представление будет больше экрана и будет содержать все подэлементы, такие как кнопки, метки, ... назовем его ' охватывающий вид ').
  4. Пусть размер Y этого внешнего вида в инспекторе размеров, например, равен 800.
  5. Поместите метку на внешний вид, где-нибудь в позиции 200 по оси Y, назовите ее «метка 1».
  6. Уловка 2 : убедитесь, что выбрано охватывающее представлениене scrollView! ), И установите его положение Y, например, на -250, чтобы вы могли добавить элемент, который находится «вне» экрана.
  7. Добавьте ярлык где-нибудь в нижней части экрана и назовите его "ярлык 2". Этот ярлык фактически находится «вне экрана».
  8. Сбросьте положение Y охватывающего вида на 0, вы больше не увидите метку 2, поскольку она была расположена за пределами экрана.

Пока что для раскадровки вам нужно добавить одну строку кода в метод viewDidLoad viewController, чтобы установить содержимое scrollViews таким образом, чтобы оно содержало все «включающее представление». Я не нашел способа сделать это в раскадровке:

- (void)viewDidLoad
{
    [super viewDidLoad];

    self.scrollView.contentSize = CGSizeMake(320, 800);
}

Вы можете попробовать сделать это, добавив contentSizekeyPath в качестве a sizeк scrollView в Identity Inspector и установив для него значение (320, 1000).

Я думаю, что Apple должна упростить это в раскадровке, в TableViewController вы можете просто прокрутить за пределами экрана в Storyboard (просто добавьте 20 ячеек, и вы увидите, что вы можете просто прокрутить), это должно быть возможно и с ScrollViewController.

Ронни Веберс
источник
1
это правильно, jaxvy, когда я недавно перенес свое приложение для поддержки автоматической компоновки, я заменил scrollview на статическое табличное представление. Выполняет ту же работу, но имеет некоторые дополнительные преимущества.
Ронни Веберс
А как насчет динамического изменения contentSize, потому что все iPhone имеют разные размеры,
veeresh kumbar
8

Получение работы прокрутки в iOS7 и автоматического макета в iOS 7 и XCode 5.

В дополнение к этому: https://stackoverflow.com/a/22489795/1553014

По-видимому, все, что нам нужно сделать, это:

  1. Установите все ограничения в режим прокрутки (т.е. сначала исправьте режим прокрутки)

  2. Затем установите ограничение distance-from-scrollView на самый нижний элемент для прокрутки представления (которое является супер-представлением).

Примечание. На шаге 2 в раскадровке будет указано, где последний фрагмент содержимого находится в режиме прокрутки.

Раджа Рао
источник
7

В этом примере я снял отметку с функции Autolayout конструктора интерфейсов. И я все еще использую (без всякой причины) относительно старую версию Xcode 4.6.1.

Начните с контроллера представления, над которым есть прокрутка (основное представление).

1: Добавить представление контейнера из библиотеки объектов в представление прокрутки. Обратите внимание, что в раскадровку добавлен новый контроллер представления, который связан с контроллером представления с помощью представления прокрутки.

2: Выберите представление контейнера и в Инспекторе размеров закрепите его сверху и слева без автоматического изменения размера.

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

3: Измените его высоту на 1000. (В этом примере используется 1000. Вы должны применить требуемое значение.)

4: Выберите новый контроллер представления и в Инспекторе атрибутов измените размер на Freeform.

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

5: Выберите представление нового контроллера представления и в Инспекторе размеров измените высоту на 1000 (что равно высоте представления контейнера).

6: Для вашего теста позже, все еще находясь в представлении нового контроллера представления, добавьте метку вверху и внизу представления.

7: Выберите представление прокрутки из исходного контроллера представления. В Инспекторе удостоверений добавьте атрибут с keyPath, установленным на contentSize, type установлен на Size, а значение установлено на {320, 1000} (или размер вашего представления контейнера).

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

8: Запустите 4-дюймовый iPhone Simulator. Вы должны иметь возможность прокручивать от верхнего ярлыка до нижнего ярлыка.

9. Запустите симулятор iPhone с диагональю 3,5 дюйма. Вы должны иметь возможность прокручивать от верхнего ярлыка до нижнего ярлыка.

Помните, что Xcode 4.6.1 можно собирать только для iOS6 и ниже. Используя этот подход и создавая для iOS6, я все еще могу добиться тех же результатов, когда приложение запущено на iOS7.

yoninja
источник
5

Обратите внимание, что внутри a UITableViewвы можете фактически прокручивать табличное представление, выбрав ячейку или элемент в ней и прокручивая вверх или вниз с помощью трекпада.

Для a UIScrollViewмне нравится предложение Алекса, но я бы рекомендовал временно изменить контроллер представления на произвольную форму, увеличить высоту корневого представления, создать свой пользовательский интерфейс (шаги 1-5), а затем вернуть его к стандартному предполагаемому размеру, когда вы закончите так что вам не нужно жестко кодировать размеры содержимого в качестве атрибутов времени выполнения. Если вы сделаете это, вы столкнетесь с множеством проблем с обслуживанием, пытаясь поддерживать как 3,5-дюймовые, так и 4-дюймовые устройства, а также с возможностью увеличения разрешения экрана в будущем.

Кайл Клегг
источник
4

Вы должны только установить свойство contentSize в viewDidAppear, как в этом примере:

- (void)viewDidAppear:(BOOL)animated{

     [super viewDidAppear:animated];
     self.scrollView.contentSize=CGSizeMake(306,400.0);

}

Он решает проблемы с автоматическим размещением и отлично работает на iOS7.

Лусио Фонсека
источник
ПРИМЕЧАНИЕ. Алекс Заватоне предлагает альтернативный способ установки contentSize без написания кода.
ToolmakerSteve
4

Отказ от ответственности: - Только для ios 9 и выше (Stack View).

Если вы развертываете свое приложение на устройствах iOS 9, используйте представление стека . Вот шаги: -

  1. Добавить вид прокрутки с ограничениями - закрепить слева, справа, снизу, сверху (без полей) в супервизор (просмотр)
  2. Добавьте представление стека с такими же ограничениями для прокрутки представления.
  3. Другие ограничения просмотра стека: - stackView.bottom = view.bottom и stackView.width = scrollView.width
  4. Начните добавлять свои взгляды. Представление прокрутки решит прокрутку в зависимости от размера представления стека (который, по сути, является представлением вашего содержимого)
DharinS
источник
1
Это полезный метод, который сводит к минимуму количество ограничений, которые необходимо добавлять вручную. В общем, способ прокрутки состоит в том, чтобы убедиться в наличии достаточных ограничений для автоматического размещения для расчета размера содержимого. Представление стека делает большую часть этого ограничения за вас. Установите стек так, spacingчтобы между подпредставлениями (дочерними элементами) было немного места. Если нужно больше места между двумя подпредставлениями, добавьте дочерний элемент-разделитель: прозрачный UIView фиксированного размера.
ToolmakerSteve
4

В iOS7 я обнаружил, что если бы у меня был View внутри UIScrollView на ViewController размером с FreeForm, он не прокручивался в приложении, что бы я ни делал. Я поигрался и обнаружил, что работает следующее, в котором не используются FreeForms:

  1. Вставьте UIScrollView в основное представление ViewController

  2. Установите соответствующие ограничения Autolayout для ScrollView. Для меня я использовал 0 для руководства по макету сверху и 0 для руководства по макету снизу.

  3. Внутри ScrollView разместите представление контейнера. Установите любую высоту, которую хотите (например, 1000).

  4. Добавьте ограничение высоты (1000) к контейнеру, чтобы его размер не изменялся. Дно будет за концом формы.

  5. Добавьте строку [self.scrollView setContentSize: CGSizeMake (320, 1000)]; в ViewController, который содержит scrollView (который вы подключили как IBOutlet)

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

nh32rg
источник
Я поддержал этот ответ, потому что мне нравится техника; однако я считаю, что вы ошибаетесь, говоря, что FreeForm VC мешает прокрутке независимо от версии iOS. Начиная с iOS 6 (в которой добавлен автоматический макет), будет прокручиваться полный набор ограничений, как описано в других ответах . Я не думаю, что FreeForm этому мешает (хотя я не пробовал). Возможно, вы упустили какое-то неочевидное ограничение; ScrollView + AutoLayout - это что-то вроде взлома.
ToolmakerSteve
3

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

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

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

все понятно, легко, элегантно и работает как шарм на ios 7. я очень доволен всем этим lol

jungle_mole
источник
ваше решение (если вы перейдете по ссылке до конца) включает добавление строки кода, так что это не совсем соответствует вопросу - с использованием только раскадровки
Борис Гафуров
@BorisGafurov, в любом случае, он немного устарел с ios7. и mb это не в соответствии, но я уверен, что это все равно помогло нескольким людям .. так что пусть будет
jungle_mole
3

Вот простое решение.

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

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

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

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

Hulk_SMASH
источник
2

Вот немного грязный ответ, который дает то же самое решение для представлений с вертикальной прокруткой, но (вопреки духу stackoverflow) не отвечает на вопрос. Вместо использования scrollView просто используйте UITableView, перетащите обычный UIView в заголовок и сделайте его настолько большим, насколько хотите, теперь вы можете прокручивать содержимое в раскадровке.

TimWhiting
источник
ИМХО, это прекрасный ответ, а не против духа stackoverflow, предлагающий альтернативный подход (если OP специально не говорит, что им нужно делать это так, как они просят.) И самая большая ценность stackoverflow - помочь всем другим людям, которые приходят вместе и прочтите вопросы и ответы. :)
ToolmakerSteve
1

Вот как настроить scrollview с помощью Xcode 11

1 - Добавить прокрутку и установить верхние, нижние, ведущие и конечные ограничения

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

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

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

3 - Перетащите из представления содержимого в руководство по макету кадра и выберите «Равная ширина».

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

4 - Установите константу ограничения высоты для представления содержимого

JP Aquino
источник
0

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

Я просто последовал этому руководству, и все сработало: http://natashatherobot.com/ios-autolayout-scrollview/

(Дополнительное примечание: нет необходимости реализовывать viewDidLayoutSubviews, если вы не хотите центрировать представление, поэтому список шагов еще короче).

Надеюсь, это поможет!

Лукаш Червински
источник
0

Ключ - contentSize.

Это часто отсутствует и не указывается при добавлении UIScrollView.

Выберите UIScrollView и выберите Инспектор удостоверений.

Добавьте contentSizekeyPath как a sizeв scrollView в Identity Inspector и установите для него значение (320, 1000).

Прокрутите.

Алекс Заватоне
источник
Это один из подходов, и я сам его использовал. Однако я не считаю это предпочтительным подходом. Это «чище / гибче», чтобы предоставить полный набор ограничений, так что автоматическое размещение может самостоятельно рассчитывать размер содержимого. Три альтернативы: ограничения сверху вниз , использование представления стека или ограничение положения нижнего элемента .
ToolmakerSteve
0

Если вы используете автоматическую компоновку, лучше всего использовать UITableViewController со статическими ячейками в раскадровке.

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

Усман Аван
источник