Как я могу программно принудительно остановить прокрутку в UIScrollView? - PullRequest
70 голосов
/ 05 августа 2010

Примечание: ответ , данный здесь , не работает для меня.

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

[scrollView scrollRectToVisible:CGRectInset([scrollView bounds], 10, 10) animated:NO];

по теории, что, учитывая уже известный видимый прямоугольник, прокрутка просто остановится, где он есть, но оказывается, что это не имеет никакогоэффект - по-видимому, представление прокрутки видит, что данный прямоугольник находится в границах и не предпринимает никаких действий.Я могу заставить остановить прокрутку, если я дам прямоугольник, который определенно находится вне видимых в данный момент границ, но внутри contentSize представления.Кажется, это останавливает вид, как и ожидалось ... но также заставляет его перейти в другое место.Я мог бы, вероятно, немного поиграть на полях, чтобы заставить это работать достаточно хорошо, но кто-нибудь знает, как правильно остановить просмотр прокрутки, который делает свое дело?

Спасибо.

Ответы [ 10 ]

98 голосов
/ 06 августа 2010

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

Обобщенное решение для любого действия прокруткиthis:

- (void)killScroll 
{
    CGPoint offset = scrollView.contentOffset;
    offset.x -= 1.0;
    offset.y -= 1.0;
    [scrollView setContentOffset:offset animated:NO];
    offset.x += 1.0;
    offset.y += 1.0;
    [scrollView setContentOffset:offset animated:NO];
}

[Edit] Начиная с iOS 4.3 (и, возможно, ранее), это также, кажется, работает

- (void)killScroll 
{
    CGPoint offset = scrollView.contentOffset;
    [scrollView setContentOffset:offset animated:NO];
}
75 голосов
/ 25 апреля 2014

Фактический общий ответ таков: [scrollView setContentOffset:offset animated:NO] - это не то же самое , что и [scrollView setContentOffset:offset]!

  • [scrollView setContentOffset:offset animated:NO] фактически останавливает любую запущенную анимацию.
  • [scrollView setContentOffset:offset] не останавливает работающую анимацию.
  • То же самое для scrollView.contentOffset = offset: не останавливает работающую анимацию.

Это нигде не задокументировано, но это поведение, протестированное на iOS 6.1 и iOS 7.1 - возможно, также раньше.

Таким образом, решение для остановки запущенной анимации / замедления просто так:

[scrollView setContentOffset:scrollView.contentOffset animated:NO];

Ну, в основном то, что сказал Дэвид Лю в своем отредактированном ответе. Но я хотел пояснить, что эти два API НЕ одинаковы.

Swift 3:

scrollView.setContentOffset(scrollView.contentOffset, animated: false)
68 голосов
/ 01 февраля 2013

Для меня Принятый Дэвидом Луи ответ выше не сработал для меня.Вот что я в итоге сделал:

- (void)killScroll {
    self.scrollView.scrollEnabled = NO;
    self.scrollView.scrollEnabled = YES;
}

Для чего бы это ни стоило, я использую iPhone 6.0 iPhone Simulator.

17 голосов
/ 20 мая 2015

Это то, что я делаю для своих видов прокрутки и всех других связанных подклассов:

- (void)scrollViewWillEndDragging:(UIScrollView *)scrollView withVelocity:(CGPoint)velocity targetContentOffset:(inout CGPoint *)targetContentOffset
 {
    *targetContentOffset = scrollView.contentOffset;
 }

Это устанавливает targetContentOffset на текущее смещение scrollView, таким образом, прокрутка останавливается, потому чтооно достигло цели.На самом деле имеет смысл использовать метод, цель которого состоит в том, чтобы пользователи могли устанавливать целевые значения contentOffset.

Swift

func scrollViewWillEndDragging(_ scrollView: UIScrollView, withVelocity velocity: CGPoint, targetContentOffset: UnsafeMutablePointer<CGPoint>) {
    targetContentOffset.pointee = scrollView.contentOffset
}
.
16 голосов
/ 02 ноября 2016

Остановить прокрутку в swift :

scrollView.setContentOffset(scrollView.contentOffset, animated: false)
12 голосов
/ 13 июля 2014

На самом деле ... Самый "современный" способ был бы ->

scrollview.panGestureRecognizer.enabled = false;
scrollview.panGestureRecognizer.enabled = true;

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

Редактировать: это фактически просто убивает текущее перетаскивание пользователя, но не сразу останавливает замедление, если в данный момент режим прокрутки находится в этом состоянии. Чтобы сделать это, редактировать принятые ответы в значительной степени является лучшим способом xD

[scrollview setContentOffset: scrollview.contentOffset animated:false];
5 голосов
/ 05 августа 2010

Самым чистым способом будет создание подкласса UIScrollView и предоставление собственного метода setContentOffset. Это должно передать сообщение, только , если вы не включили логическое свойство freeze.

Вот так:

BOOL freeze; // and the @property, @synthesize lines..

-(void)setContentOffset:(CGPoint)offset
{
    if ( !freeze ) [super setContentOffset:offset];
}

Затем, чтобы заморозить:

scrollView.freeze = YES;
4 голосов
/ 10 июля 2015

Этот ответ сработал для меня: Отключить UIScrollView, замедляется

-(void)scrollViewWillBeginDecelerating:(UIScrollView *)scrollView{
    [scrollView setContentOffset:scrollView.contentOffset animated:YES];
}
0 голосов
/ 23 июня 2019

Это работает для меня в Swift 4.2 :

   func killScroll() {
    self.scrollView.isScrollEnabled = false;
    self.scrollView.isScrollEnabled = true;
}

... как расширение:

extension UIScrollView {
    func killScroll() {
        self.isScrollEnabled = false;
        self.isScrollEnabled = true;

    }
}
0 голосов
/ 05 декабря 2016

Я попробовал этот метод в collectionview:

self.collectionView.collectionViewLayout.finalizeCollectionViewUpdates()

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