UISCrollView仅在底部禁用垂直反弹



我一直在寻找一种禁用垂直反弹的方法,以获取uiscrollview,但仅在底部。我仍然需要在顶部弹跳。

找不到任何东西。这可能吗?

预先感谢!

使用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)];
    }
}

在swift中禁用垂直反弹:

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

在Swift中禁用垂直反弹:

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

基于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 S具有这种反弹行为(例如UIWebView的一个)。

再次,谢谢 @0x7ffffffff解决方案!

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
    }
}

当滚动到底部时,让我们禁用bounces

scrollView.bounces = scrollView.contentOffset.y < scrollView.contentSize.height - scrollView.frame.height

我将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)];
    }
}

我一直在寻找一种解决方案,以使底部弹跳仅用于比设备更宽的滚动浏览,因为我使用的是分页。这些都不适合我,但我找到了一种方法。我以为我应该分享这一点,因为我浪费了两天才能做到这一点。我正在使用Swift 4,但是如果您知道如何转换它,则适用于目标C,如果您有两者都有经验,那应该很容易。

这在带有设备屏幕框架的滚动浏览中起作用。

  1. 添加变量以了解Scrollview的当前页面。
    var currentPage : Int!

  2. 设置初始值
    currentPage = 0

  3. 滚动后更新currentPage
    public func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) { let width = scrollView.frame.size.width let page = (scrollView.contentOffset.x + (0.5 * width)) / width currentPage = Int(page) }

  4. 过滤底部滚动和更新contentoffset
    public func scrollViewDidScroll(_ scrollView: UIScrollView) { if CGFloat(currentPage) * screenWidth < scrollView.contentOffset.x || CGFloat(currentPage) * screenWidth < scrollView.contentOffset.y || (((CGFloat(currentPage) * screenWidth - scrollView.contentOffset.x) >= 0) && scrollView.contentOffset.y > 0){ scrollView.contentOffset.y = 0 } }

CGFloat(currentPage) * screenWidth < scrollView.contentOffset.x || CGFloat(currentPage) * screenWidth < scrollView.contentOffset.y将过滤左下和右下角

(((CGFloat(currentPage) * screenWidth - scrollView.contentOffset.x) >= 0) && scrollView.contentOffset.y > 0)将过滤底部滚动

scrollView.contentOffset.y = 0将阻止其滚动

最新更新