Подтвердить что ты не робот

UIScrollView отключает вертикальный отскок только снизу

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

Не удалось найти ничего. Возможно ли это?

Спасибо заранее!

4b9b3361

Ответ 1

Используйте метод UIScrollViewDelegate scrollViewDidScroll, чтобы проверить смещение содержимого прокрутки и более или менее проверить, пытается ли пользователь прокручиваться за пределы нижних границ прокрутки. Затем просто используйте это, чтобы установить прокрутку обратно до конца прокрутки. Это происходит так быстро, что вы даже не можете сказать, что просмотр прокрутки отскочил или выходил за пределы.

- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
    if (scrollView.contentOffset.y >= scrollView.contentSize.height - scrollView.frame.size.height) {
        [scrollView setContentOffset:CGPointMake(scrollView.contentOffset.x, scrollView.contentSize.height - scrollView.frame.size.height)];
    }
}

Ответ 2

Чтобы отключить вертикальный отскок вверху в Swift:

func scrollViewDidScroll(scrollView: UIScrollView) {
    if scrollView.contentOffset.y < 0 {
        scrollView.contentOffset.y = 0
    }
}

Ответ 3

На основании ответа 0x7fffffff я создал класс:

VerticalBounceControl.h

#import <UIKit/UIKit.h>

@interface VerticalBounceControl : NSObject

@property (nonatomic, assign) BOOL bounce;

- (id) initWithScrollView:(UIScrollView*)scrollView bounceAtTop:(BOOL)bounceAtTop bounceAtBottom:(BOOL)bounceAtBottom;

@end

VerticalBounceControl.m

#import "VerticalBounceControl.h"

@interface VerticalBounceControl ()
@property (nonatomic, retain) UIScrollView* scrollView;
@property (nonatomic, assign) BOOL bounceAtTop;
@property (nonatomic, assign) BOOL bounceAtBottom;
@end

@implementation VerticalBounceControl

- (id) initWithScrollView:(UIScrollView*)scrollView bounceAtTop:(BOOL)bounceAtTop bounceAtBottom:(BOOL)bounceAtBottom {
    self = [super init];
    if(self) {
        self.bounce = YES;
        self.scrollView = scrollView;
        self.bounceAtTop = bounceAtTop;
        self.bounceAtBottom = bounceAtBottom;
        [self.scrollView addObserver:self forKeyPath:@"contentOffset" options:NSKeyValueObservingOptionNew context:NULL];
    }
    return self;
}

- (void) dealloc {
    [self.scrollView removeObserver:self forKeyPath:@"contentOffset"];
    self.scrollView = nil;
}

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context {
    if ([keyPath isEqualToString:@"contentOffset"]) {
        if (self.bounce && ((self.scrollView.contentOffset.y<=0 && self.bounceAtTop) || (self.scrollView.contentOffset.y>=self.scrollView.contentSize.height-1 && self.bounceAtBottom))) {
            self.scrollView.bounces = YES;
        } else {
            self.scrollView.bounces = NO;
        }
    }
}

@end

который может использоваться без вызывающего объекта, являющегося делегатом UIScrollView следующим образом:

VerticalBounceControl* bounceControl = [[VerticalBounceControl alloc] initWithScrollView:anyScrollView bounceAtTop:YES bounceAtBottom:NO];

Таким образом, вы можете иметь это поведение отказов для UIScrollView, которое вы не хотите изменять своего делегата (например, UIWebView one).

Еще раз спасибо @0x7fffffff за решение!

Ответ 4

Я добавил fabsf() в 0x7fffffff ♦ решение, которое также поддерживает отрицательную (вниз) прокрутку:

- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
    if (fabsf(scrollView.contentOffset.y) >= scrollView.contentSize.height - scrollView.frame.size.height) {
        [scrollView setContentOffset:CGPointMake(scrollView.contentOffset.x, scrollView.contentSize.height - scrollView.frame.size.height)];
    }
}

Ответ 5

Swift 3:

Это работает, чтобы отключить вертикальный отскок только внизу:

func scrollViewDidScroll(_ scrollView: UIScrollView) {
    if scrollView.contentOffset.y > scrollView.contentSize.height - scrollView.bounds.height {
        scrollView.contentOffset.y = scrollView.contentSize.height - scrollView.bounds.height
    }
}