Як відключити горизонтальну прокрутку UIScrollView?


92

У мене є UIViewсхожий на трамплін iPhone. Я створив його за допомогою UIScrollViewі UIButtons. Я хочу відключити горизонтальну прокрутку на вказаному прокручуваному перегляді. Я хочу лише вертикальну прокрутку. Як мені це досягти?


5
Вам слід змінити заголовок: ви просите горизонталь у питанні та вертикаль у назві. Люди знаходять ваші запитання пізніше в пошукових системах, тому це все одно має значення через 2 роки :)
Жюльєн

@RahulVyas Чоловік вище має сенс. Зміна заголовка зменшить будь-яку плутанину для початківців, які потрапляють сюди через пошукову систему (наприклад, я;)).
SpacyRicochet

Редагували заголовок від імені плаката. (Хоча наразі це очікує експертної перевірки, перш ніж редагування буде видно.)
Duncan Babbage

Відповіді:


125

Ви повинні встановити contentSizeвластивість UIScrollView. Наприклад, якщо ваш UIScrollViewекран має ширину 320 пікселів (ширина екрана), ви можете зробити це:

CGSize scrollableSize = CGSizeMake(320, myScrollableHeight);
[myScrollView setContentSize:scrollableSize];

Потім UIScrollViewволя прокручується лише вертикально, оскільки вона вже може відображати все по горизонталі.


6
Привіт. Це рішення працює дуже добре! Дякую за це. Я спробував встановити статичну ширину на 0. Для мене це теж працює. Не знаю, чи пізніше можуть бути якісь побічні ефекти. Але якщо хтось не знає розмір (тобто універсальний код для iPhone та iPad), це чудово працює!
JackPearse

5
Я думаю, що краще зробити CGSizeMake (0, myScrollableHeight), тому горизонтальна прокрутка вимкнена, навіть якщо не всі підпрограми відображалися.
LightNight

Примітка. Якщо встановити один із розмірів на 0 при використанні підкачки, VoiceOver повідомить номер сторінки як "сторінку 1 з 1", незалежно від правильного значення
josef

1
Замість того, щоб передавати ширину як жорстко закодовану 320, ми можемо передати, як: CGSize scrollableSize = CGSizeMake (self.scrollview.frame.size.width, myScrollableHeight); [myScrollView setContentSize: scrollableSize];
Мохіт кумар,

90

ОНОВЛЕНО: (Після того, як @EranMarom зазначив у своєму коментарі)

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

Зупиняє горизонтальну прокрутку:

Якщо ви хочете прокручувати горизонтально, вам потрібно збільшити contentOffset.x. Запобігання зупинці прокрутки перегляду в горизонтальному напрямку.

- (void)scrollViewDidScroll:(UIScrollView *)sender {
    sender.contentOffset.x = 0.0
}

Зупиняє вертикальну прокрутку:

Якщо ви хочете прокручувати вертикально, вам потрібно збільшити contentOffset.y. Запобігання зупинці прокрутки перегляду у вертикальному напрямку.

- (void)scrollViewDidScroll:(UIScrollView *)sender {
    sender.contentOffset.y = 0.0
}

Наведений вище код запобігає змінам в xі ya, scrollview contentOffsetі це призводить до зупинки прокрутки в scrollViewDidScroll:методі.


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

13
Це свого роду хакерство, але це спрацювало, коли все інше не вдалося. Тож +1, але використовуйте лише в крайньому випадку.
i_am_jorf

5
Я також використовую цей метод делегування, але замінюю тіло на однорядковий, наприклад: scrollView.contentOffset = CGPointMake(0, scrollView.contentOffset.y);щоб вимкнути горизонтальну прокрутку. Я вважаю його більш читабельним, він менший, і немає сенсу робити тест на нуль, оскільки практично немає накладних витрат з кодом, які запускають це рідко (тобто кілька десятків разів на секунду макс.).
Ешелон

тому що ви змінюєте contentOffset після "didscroll", а не так, як раніше "willscroll", і це рішення молотка, але я сам не проголосував проти, тому що 18 за і відповідь 75, тому не варто проголосувати
LolaRun

2
Ще простіше - використовувати scrollView.contentOffset.y = 0.0для зупинки вертикальної прокрутки та scrollView.contentOffset.x = 0.0зупинки горизонтальної прокрутки у функції scrollViewDidScroll()делегування. Однак я вважаю, що переконатися, що scrollView.contentSizeдорівнює, scrollView.frame.sizeє кращим (правильним) рішенням. Дивіться відповідь @danbeaulieu.
emem

11

з часу використання iOS7

self.automaticallyAdjustsScrollViewInsets = NO;

// і створимо вам прокрутку сторінки з 3 сторінками

    self.pageView = [[UIScrollView alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height)];
    [self.pageView setContentSize:CGSizeMake(self.view.frame.size.width*3, self.view.frame.size.height)];
    [self.pageView setShowsVerticalScrollIndicator:NO];
    [self.pageView setPagingEnabled:YES];
    [self.view addSubview:self.pageView];

Я не думаю, що це відключить поведінку прокрутки перегляду прокрутки. Є це??
Dinesh Raja

self.collectionView.pagingEnabled = YES;допомогло мені вирішити проблему з плавним прокручуванням (не перетягуванням). Проблема була в методі scrollViewWillEndDragging:- targetContentOffset був таким самим, як і scrollView.contentOffset, і логіка виявлення сторінок не працює належним чином.
sig

11

Швидке рішення

Створіть дві торгові точки, одну для вашого перегляду, а другу для перегляду прокрутки:

@IBOutlet weak var myView: UIView!
@IBOutlet weak var scrollView: UIScrollView!

Тоді у ваш viewDidLayoutSubviews ви можете додати такий код:

let scrollSize = CGSize(width: myView.frame.size.width, 
                        height: myView.frame.size.height)
scrollView.contentSize = scrollSize

Що ми зробили, збираємо висоту та ширину подання та встановлюємо розмір вмісту scrollViews відповідно до нього. Це зупинить ваше прокручування з горизонтальної прокрутки.


Більше думок:

CGSizeMake приймає ширину та висоту за допомогою CGFloats. Можливо, вам доведеться використовувати існуючу висоту вашого UIScrollViews для другого параметра. Що виглядатиме так:

let scrollSize = CGSize(width: myView.frame.size.width, 
                        height: scrollView.contentSize.height)

Що робити, якщо ви не знаєте висоту чи ширину (універсальний пристрій)? @danbeaulieu
Lukesivi

@lukesIvi "myView.frame.width" динамічно витягує ширину з IBOutlet "myView".
Dan Beaulieu

4

У моєму випадку з Swift 4.2 ви можете використовувати:

Вимкнути вертикальну прокрутку:

func scrollViewDidScroll(_ scrollView: UIScrollView) {
    scrollView.contentOffset.y = 0.0
}

Вимкнути горизонтальну прокрутку:

func scrollViewDidScroll(_ scrollView: UIScrollView) {
    scrollView.contentOffset.x = 0.0
}

3

Ви можете вибрати вид, а потім Attributes Inspectorзніміть прапорець User Interaction Enabled.


3

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

Сподіваюся, це допоможе комусь


@Nostradamus радий допомогти
Gulfam Khan

0

У мене було встановлено tableview contentInset у viewDidLoad (як показано нижче), що спричиняє горизонтальну прокрутку

self.tableView.contentInset = UIEdgeInsetsMake(0, 30, 0, 0);

Перевірте, чи є для будь-якої таблиці вміст contentInset встановлений з різних причин, і вимкніть його


0

Я певний час боровся з цим, безуспішно намагаючись різні пропозиції в цій та інших темах.

Однак в іншому потоці (не впевнений де) хтось припустив, що використання негативного обмеження на UIScrollView спрацювало для нього.

Тож я спробував різні комбінації обмежень з непослідовними результатами. Що врешті-решт у мене спрацювало, це додати провідні та кінцеві обмеження -32 до перегляду прокрутки та додати (невидимий) перегляд тексту шириною 320 (і по центру).


0

Спробуйте це:

CGSize scrollSize = CGSizeMake([UIScreen mainScreen].bounds.size.width, scrollHeight);
[scrollView setContentSize: scrollSize];

0

Вимкніть горизонтальну прокрутку, замінивши contentOffsetвластивість у підкласі.

override var contentOffset: CGPoint {
  get {
    return super.contentOffset
  }
  set {
    super.contentOffset = CGPoint(x: 0, y: newValue.y)
  }
}

0

Введено в iOS 11 - це нова властивість на UIScrollView

var contentLayoutGuide: UILayoutGuide

У документації зазначено, що ви:

Використовуйте цей посібник із макету, коли ви хочете створити обмеження для автоматичного макета, пов’язані з областю вмісту подання прокрутки.

Поряд з будь-якими іншими обмеженнями авторозкладки, які ви могли б додати, ви хочете обмежити widthAnchorзначення UIScrollView'' s contentLayoutGuideтаким самим розміром, як "кадр". Ви можете використовувати frameLayoutGuide(також представлену в iOS 11) або будь-яку зовнішню ширину (наприклад, вашу superView.)

приклад:

NSLayoutConstraint.activate([
  scrollView.contentLayoutGuide.widthAnchor.constraint(equalTo: self.widthAnchor)
])

Документація: https://developer.apple.com/documentation/uikit/uiscrollview/2865870-contentlayoutguide



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