UIScrollView не прокручується


128

У мене є UIScrollViewякий містить багато UIImageViews, UILabels тощо. Мітки набагато довші, ніж UIScrollView, але коли я запускаю програму, я не можу натискати та прокручувати вниз ...

Чому це може бути?

Дякую


Новий 26.03.2013 Я натрапив на простіший спосіб зробити це без коду (встановлення contentSize) stackoverflow.com/a/15649607/1705353
Dickey Singh

Відповіді:


169

Завжди добре показати повний фрагмент робочого коду:

// in viewDidLoad (if using Autolayout check note below):

UIScrollView *myScrollView;
UIView *contentView;
// scrollview won't scroll unless content size explicitly set

[myScrollView addSubview:contentView];//if the contentView is not already inside your scrollview in your xib/StoryBoard doc

myScrollView.contentSize = contentView.frame.size; //sets ScrollView content size

Swift 4.0

let myScrollView
let contentView

// scrollview won't scroll unless content size explicitly set

myScrollView.addSubview(contentView)//if the contentView is not already inside your scrollview in your xib/StoryBoard doc

myScrollView.contentSize = contentView.frame.size //sets ScrollView content size

Я не знайшов способу встановити contentSize в IB (станом на Xcode 5.0) .

Примітка: Якщо ви використовуєте Autolayout, найкраще розмістити цей код - всередині -(void)viewDidLayoutSubviewsметоду.


12
Не забудьте встановити myScrollView.delegate = selfТАКОЖ, якщо це все ще не працює, відповідь нижче цього має ВЕЛИКІ поради (перейдіть на ваш xib / StoryBoard і переконайтесь, що функція "Автоматична розробка" відключена). Порада: Ви також можете включити <UIScrollViewDelegate>у свій .h файл, якщо ви хочете робити такі речі, як програмне прокручування вашого UIScrollView.
Альберт Реншо

1
@AlbertRenshaw, ти мав би додати відповідь, щоб я міг дати вам +1 :) Проблема з AutoLayout була зі мною .... змусила мене божевільно протягом 4 годин.
логіксолог

2
Введення коду viewDidLayoutSubviewsзмусило мене працювати.
Amr Lotfy

Для мене проблема полягала в тому, що не потрібно прокручувати, як все вміщується на екрані.
Даніель Спрінгер

122

Якщо ви не можете прокрутити представлення даних навіть після того, як ви правильно встановили contentSize , переконайтесь, що зніміть прапорець "Використовувати автоматичну розкладку" в "Інтерфейсі" -> Інспектор файлів.


164
Крім того , ви можете встановити contentSize в viewDidLayoutSubviews: і він буде застосовуватися після того , як autolayout завершується.
Кріс Васселлі

2
@ "Chris Vasselli" slove мій випуск .. GR8 .. :-)
Ayaz

3
Коментар Кріса має бути окремою відповіддю!
ninjaneer

1
Дякую тобі Кріс Васселлі! Якщо ввімкнено автоматичний макет, він не працюватиме у viewDidLoad, але це робиться з viewDidLayoutSubviews!
Ромен

1
Вау, я ніколи не помічав усіх цих коментарів раніше! Радий, що я можу допомогти багатьом з вас! Я щойно опублікував окрему відповідь, тому, сподіваюся, її буде легше знайти.
Кріс Васселлі

68

Вам потрібно встановити contentSize властивість перегляду прокрутки, щоб він міг правильно прокручуватися.

Якщо ви використовуєте autolayout, вам необхідно встановити contentSizeв viewDidLayoutSubviewsдля того , щоб застосовувати його після autolayout завершується.

Код може виглядати так:

-(void)viewDidLayoutSubviews
{
    // The scrollview needs to know the content size for it to work correctly
    self.scrollView.contentSize = CGSizeMake(
        self.scrollContent.frame.size.width,
        self.scrollContent.frame.size.height + 300
    );
}

Дякую тонна .. Це спрацювало, тому що чомусь навіть коли я встановлюю значення contentSizeрозміру contentView, розмір scrollView і contentView, здається, встановлюється однаковим. Але встановивши висоту contentSizeна значення, що перевищує висоту contentView, воно спрацювало.
Скайуокер

viewDidLayoutSubviewsВи можете викликати кілька разів протягом життєвого циклу, тому ви ризикуєте збільшити висоту, більшу, ніж очікувалося.
anon_nerd

@anon_nerd просто перевірте, чи він уже викликався, і додайте лише висоту, якщо ні
Daniel Springer

45

Відповідь вище правильна - для того, щоб прокручування відбулося, потрібно встановити розмір вмісту.

Якщо ви використовуєте конструктор інтерфейсів акуратний спосіб зробити це за допомогою визначених користувачем атрибутів виконання. Наприклад:

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


це нічого не зробило для мене.
coolcool1994

4
На жаль, на малюнку показано {0, 0}, але ви, звичайно, повинні ввести достатньо великі цифри. . такий підхід працюватиме лише для простих представлень, де ви знаєте розмір вмісту наперед. . . (насправді для складних поглядів я все-таки рекомендую чистий код).
Jasper Blues

Набагато менше хакі, ніж це робити програмно. Дякую!
Джейк Стоффлер

1
@JakeStoeffler Ласкаво просимо! :) Під час використання IB я люблю зберігати всі конфігурації там (не фрагментовані). Але коли речі стають складними (віджети перегляду для багаторазового використання; адаптери моделі, маніпуляції з шарами; CAAnimations тощо), то я віддаю перевагу повністю програмним уявленням. . . більш вільне.
Джаспер Блюз

Я спробував це, працює, коли з'являється перегляд, але при зміні орієнтації зміст розміру, визначений на екрані вище, ігнорується, і мій журнал говорить, що зміст розміру встановлено назад 0,0. Будь-яка ідея, як це виправити?
Shoogle

40

Спробуйте змінити розмір вмісту до величезної кількості. Я не міг зрозуміти, чому в моєму вікні прокрутки не прокручується навіть тоді, коли розмір вмісту здається більшим за контрольний. Я виявив, що якщо розмір вмісту менший, ніж потрібно, він також не працює.

self.scrollView.contentSize = CGSizeMake(2000, 2000);

Замість 2000 можна поставити власні великі цифри. І якщо це працює, це означає, що розмір вмісту недостатньо великий при зміні розміру.

Делегат не потрібен, щоб перегляд прокрутки працював.


2
Геній - такий простий спосіб перевірити, що відбувається. Дякую купу!
Божевільний шимпанз

13

Переконайтеся, що ви маєте властивість contentSize у вікні прокрутки встановити правильний розмір (тобто один достатньо великий, щоб охопити весь ваш вміст.)


1
чи потрібно це робити систематично? чи я можу це зробити в IB?
Марк

Якщо ви використовуєте IB, ви можете встановити його звідти - див. Нижче. . (Окрема відповідь, тому я можу включити фотографії).
Джаспер Блюз

7

Зніміть прапорець "Використовувати автоматичне вимикання" для мене зробив фокус

Навколишнє середовище: xCode 5.0.2 Розділборди ios7


5

У моєму випадку я повинен був встановити delaysContentTouchesзначення true, тому що об'єкти всередині scrollView захоплювали події на дотику та керували собою, а не дозволяли scrollView самому обробляти це.


У мене те саме питання. Проблема для мене полягає в тому, що, перетворивши delasContentTouches на справжнє, ви закінчите малюнки нижчої якості яблучним олівцем. Але це
крайній

4

Встановити contentSizeвластивість UIScrollviewв ViewDidLayoutSubviewsметоді. Щось на зразок цього

override func viewDidLayoutSubviews() {
    super.viewDidLayoutSubviews()

    scrollView.contentSize = CGSizeMake(view.frame.size.width, view.frame.size.height)
}

3

Ідея, чому перегляд прокрутки, не прокручується, оскільки ви встановлюєте розмір вмісту для прокрутки менше, ніж розмір подання прокрутки, що неправильно. Ви повинні встановити розмір вмісту, більший за розмір подання прокрутки, щоб переміщатися по ньому під час прокрутки.

У тій же ідеї зі збільшенням ви встановлюєте значення мінімального та максимального масштабування, яке застосовуватиметься через масштабування.

Ласкаво просимо :)


3

Одне невелике доповнення, все вище - це фактичні причини, через які подання прокрутки може не прокручуватися, але іноді безглуздо це може бути причиною, особливо якщо додаток прокрутки додається через код, а не ІБ, можливо, ви додали підпогляди до батьківського виду, а не перегляд прокрутки це призводить до того, що підвід не прокручується

і зберігайте набір розміру вмісту та більше, ніж батьківський кадр перегляду (так !!)


3

Я змусив це працювати з моєї першої спроби. З автоматичним компонуванням і всіма додатковими кодами. Потім перегляд колекції перейшов на банан, під час запуску він не зміг, я не міг знайти те, що не так, тому я видалив і відтворив його (я використовую Xcode 10 Beta 4. Це відчувало, як помилка), а потім прокрутка зникла. Перегляд колекції працював знову!

Через багато годин .. це те, що мені виправило. У мене був такий макет:

UIView

  • Безпечна зона
  • Перегляд прокрутки
    • Перегляд вмісту

Це все в обмеженнях. Безпечна зона автоматично визначається системою. У гіршому випадку видаліть усі обмеження для перегляду прокрутки та вмісту і не потрібно скидати / створювати їх ІБ. Зробіть їх вручну, це працює.

  • Для перегляду прокрутки я зробив: Вирівнювання контуру / вершина до безпечної зони. Рівна ширина / висота для безпечної зони .
  • Для перегляду вмісту я зробив: вирівнювання трейлінгу / ведучого / вгору / знизу до перегляду (подання прокрутки)

По суті, концепція полягає у створенні перегляду вмісту, що відповідає Scrollview, який відповідає безпечній зоні.

Але як таке воно не спрацювало. Перегляд вмісту пропустив висоту. Я спробував усе, що міг, і єдиним, що робив трюк, був висота перегляду вмісту, створена контрольно-перетягувальним видом вмісту .. до себе . Це визначило фіксовану висоту, значення якої було обчислено з розміру контролера перегляду (визначається як вільна форма, довше реального дисплея, щоб містити всі мої підпогляди) і, нарешті, воно працювало знову!


Ви дуже раді! Я точно знаю, як ви себе почували .. ;-)
Michele Dall'Agata

Thaaaaks, я витратив багато годин, і це вирішило мою проблему
Андоні Да Сілва

3

якщо ви отримуєте повідомлення (IOS8 / swift), viewDidLayoutSubviewsяке не існує, скористайтеся наступним

override func viewDidAppear(animated: Bool)

Це зафіксувало це для мене


2

Щось, про що раніше не згадували!

Переконайтесь, що ваша розетка правильно підключена до scrollView! У ньому повинно бути заповнене коло, але навіть якщо ви заповнили коло, scrollView може бути не підключений - тому подвійно перевірте! Наведіть курсор на коло та побачите, чи дійсно виділяється фактичний прокрутка! (Це стосувалося мене)

//Connect below well to the scrollView in the storyBoard
@property (weak, nonatomic) IBOutlet UIScrollView *scrollView;

2

Багато часу код правильний, якщо ви дотримувались підручника, але те, що багато початківців не знає, це те, що scrollView НЕ збирається прокручуватись нормально через тренажер. Припустимо, прокручувати лише тоді, коли ви натискаєте на клавіатуру миші та одночасно прокручуєте. Багато досвідчених користувачів XCode / Swift / Obj-C настільки звикли робити це, і тому вони не знають, як це може не помітити початківців. Ciao :-)

@IBOutlet weak var scrollView: UIScrollView!
override func viewDidLoad() {
    super.viewDidLoad()
    view.addSubview(scrollView)
    // Do any additional setup after the view
}

override func viewWillLayoutSubviews(){
    super.viewWillLayoutSubviews()
    scrollView.contentSize = CGSize(width: 375, height: 800)
}

Цей код буде працювати чудово, доки ви не зробите те, про що я говорив вище


1

Якщо жодне з інших рішень не працює для вас, переконайтеся, що ваш перегляд прокрутки насправді є UIScrollViewв Інтерфейсі.

У якийсь момент за останні кілька днів мій UIScrollView стихійно змінив тип на "а" UIView, хоча його клас сказав UIScrollViewу інспектора. Я використовуюXcode 5.1 (5B130a) .

Можна або створити новий вид прокрутки, і скопіювати вимірювання, налаштування та обмеження зі старого перегляду, або ви можете вручну змінити свій погляд на файл UIScrollViewу xibфайлі. Я зробив порівняння і виявив такі відмінності:

Оригінал:

<scrollView clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" directionalLockEnabled="YES" bounces="NO" pagingEnabled="YES" showsHorizontalScrollIndicator="NO" showsVerticalScrollIndicator="NO" translatesAutoresizingMaskIntoConstraints="NO" id="Wsk-WB-LMH">
...
</scrollView>

Після типу спонтанно змінився:

<view clearsContextBeforeDrawing="NO" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" customClass="UIScrollView" id="qRn-TP-cXd">
...
</view>

Тому я замінив <view>рядок на свій оригінал<scrollView> лінію.

Я також замінив закриває тег виду по </view>з </scrollView>.

Не забудьте зберегти ідентичний номер таким же, як у поточному представленні, в цьому випадку: id = "qRn-TP-cXd".

Мені також довелося видалити xib з кешу Xcode, видаливши отримані дані програми:

  • Xcode->Window->Organizer->Projects, виберіть проект, у рядку Отримані дані натисніть Видалити ...

Або якщо ви користуєтесь пристроєм:

  • Xcode->Window->Organizer->Device, виберіть свій пристрій-> Програми, виберіть додаток, натисніть (-)

Тепер очистіть проект і видаліть додаток із тренажера / пристрою:

  • Xcode->Product->Clean
  • iOS Simulator/device->pressі утримуйте app->click(X), щоб видалити його

Тоді ви зможете створити та запустити свою програму та знову мати функцію прокрутки.

PS Мені не довелося встановлювати розмір вмісту подання прокрутки в viewDidLayoutSubviewsабо вимикати автоматичне розташування, але YMMV.


1

Якщо ваш scrollViewсубпогляд containerViewякогось типу, то переконайтеся, що ваш параметр scrollViewзнаходиться в межах або межах межі containerView. Я мав containerView.clipsToBounds = NOвсе ще дозволяти мені бачити scrollView, але через те, що scrollViewне знаходився в межахcontainerView він не би сенсорні події.

Наприклад:

containerView.frame = CGRectMake(0, 0, 200, 200);
scrollView.frame = CGRectMake(0, 200, 200, 200);
[containerView addSubview:scrollView];
scrollView.userInteractionEnabled = YES;

Ви зможете побачити scrollView, але він не отримає взаємодії з користувачем.


1

додавши наступний код, який viewDidLayoutSubviewsпрацював для мене з Autolayout. Спробувавши всі відповіді:

- (void)viewDidLayoutSubviews
{
    self.activationScrollView.contentSize = CGSizeMake(IPHONE_SCREEN_WIDTH, 620);

}

//set the height of content size as required

1

Додайте UIScrollViewDelegateта додайте наступний код до viewDidAppearметоду, який виправили для мене.

@interface testScrollViewController () <UIScrollViewDelegate>

-(void)viewDidAppear:(BOOL)animated {
    self.scrollView.delegate = self;
    self.scrollView.scrollEnabled = YES;
    self.scrollView.contentSize = CGSizeMake(375, 800);
}

1

Мою проблему вирішили:

  1. встановлення розміру вмісту в scrollView на велику висоту
  2. АЛЕ я також повинен був виправити обмеження на верхньому та / або нижньому поглядах у scrollView, що означало, що індикатори прокрутки відображаються на екрані, але вміст не прокручується

Після того, як я усунув верхню та / або нижню обмеження, прив’язані до безпечної зони та / або нагляд, перегляди всередині scrollView можуть прокручуватися знову і не залишатись фіксованими у верхній частині нижньої частини екрана!

Сподіваюся, це зупинить когось іншого від години болю з цим питанням.


1

ще один цікавий випадок:

scrollview.superview.userInteractionEnabled повинен бути істинним

Я витратив 2 години на це, переслідуючи це лише для того, щоб зрозуміти, що батько - це UIImageView, який, природно, має userInteractionEnabled == false


0

Після провалу наданих відповідей у ​​цій темі, я натрапив на цю статтю з рішенням.

Про налаштування прокрутки за допомогою автоматичного вимикання є не інтуїтивно зрозумілим:

  1. Обмеження, встановлені вами як межа між переглядом вмісту та прокруткою, не впливають на розмір перегляду вмісту. Вони справді є маржами. А щоб воно працювало, перегляд контенту повинен мати фіксований розмір.
  2. Підступ до фіксованого розміру полягає в тому, що ви можете встановити ширину перегляду вмісту, рівну ширині батьківського прокрутки. Просто виберіть обидва представлення на дереві зліва та додайте рівне обмеження по ширині.

Це суть цієї статті. Повне пояснення, включаючи ілюстрації, перегляньте його.


@PredragManojlovic Як це може бути більш загальним, ніж це? Це єдиний спосіб, коли я міг змусити переглядати прокрутку, щоб нормально працювати, використовуючи автоматичне компонування.
Х. де Йонге

0

Я виявив, що з цією проблемою AutoLayout ... якщо я просто ViewControllerскористаюся UIViewзамість UIScrollViewкласу ... тоді просто додаю UIScrollViewсебе ... що це працює.


0

У мене був такий самий випуск у ІБ.

Після встановлення провідного, останнього, верхнього і нижнього пункту scrollView на його супервигляд. Я вніс такі зміни, щоб контейнер ViewV прокручувався, який працював.

Щоб зробити scrollView лише прокрутку в горизонтальному напрямку, зробіть обмеження центром scrollViewY = центр ContainerViewY

і щоб зробити його вертикально прокручувальним, зробіть центр scrollViewX = центр ContainerViewX

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.