UIScrollView disable scrolling in just one directi

2019-01-21 19:28发布

问题:

I've been unable to find an answer for this (maybe someone has hacked a solution together).

Is it possible to disable scrolling in a UIScrollView in one direction? I am not talking about disabling vertical or horizontal scrolling, but one direction only. So for example, in a UIScrollView, I want to be able to drag the scrollview in a downwards direction, but not in an upwards direction

Thanks

回答1:

Turns out a simple solution was actually possible and easy:

- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
    if (scrollView.contentOffset.y > 60) {
        [scrollView setContentOffset:CGPointMake(0, 60)];
    }
}


回答2:

This works for me:

    -(void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate{
        scrollView.bounces = YES;
    }

    -(void)scrollViewDidScroll:(UIScrollView *)scrollView{

        if (scrollView.contentOffset.y < 0) {
            [scrollView setContentOffset:CGPointMake(0, 0)];
            scrollView.bounces = NO;
        }

        if (scrollView.contentOffset.y == 0){
            scrollView.bounces = YES;
        }

        else scrollView.bounces = YES;
    }


回答3:

Fortunately, we can use scrollRectToVisible to avoid jittery behavior after the scroll has been limited:

- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
    if (scrollView.contentOffset.y > 60) {
        [scrollView setContentOffset:CGPointMake(0, 60)];

        CGFloat pageWidth  = scrollView.frame.size.width;
        CGFloat pageHeight = scrollView.frame.size.height;
        CGRect rect = CGRectMake(0, 0, pageWidth, pageHeight);
        [scrollView scrollRectToVisible:rect animated:YES];
    }
}


回答4:

The above solutions will reset you to zero,zero if the user accidentally scrolls vertically. Try this...

- (void)scrollViewDidScroll:(UIScrollView *) scrollView {
    if (scrollView.contentOffset.y > 0) {
        [scrollView setContentOffset:CGPointMake(scrollView.contentOffset.x, 0)];
    }
}


回答5:

If you set the contentSize of the scroller equals to the size of the content, in one of the direction, the scroll will disappear in that direction because there will be nothing to scroll.



回答6:

An alternative might be:

- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
    if (scrollView.contentOffset.y < 10) {
        scrollView.bounces = NO;
    }

    else scrollView.bounces = YES;
}

But remember that this will only work for the scrollViews, which have a bigger content than their frames.



回答7:

Instead of using a UIScrollViewDelegate to correct the already wrong contentOffset (which will result in a jittery behaviour) you may want to consider to sub class UIScrollView instead and overriding setContentOffset:

- (void)setContentOffset:(CGPoint)contentOffset {
    if (contentOffset.y <= 60) {
        [super setContentOffset:contentOffset];
    }
}

Off course this can be generalized by adding a property for the min or max allowed value for the content offset. You may need to override setContentOffset:animated: as well.



回答8:

this works for me

static CGPoint lastOffset;

- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView {
    scrollView.scrollEnabled = YES;
}

- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView {
    scrollView.scrollEnabled = YES;
    lastOffset = scrollView.contentOffset;
}

- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
    CGPoint nowOffset = scrollView.contentOffset;
    NSLog(@"delta %f", lastOffset.x - nowOffset.x);
    if ((lastOffset.x - nowOffset.x) < 0) {
        //uncomment to prevent scroll to left
        //scrollView.scrollEnabled = NO;
    } else if ((lastOffset.x - nowOffset.x) > 0) {
        //uncomment to prevent scroll to right
        //scrollView.scrollEnabled = NO;
    } else {
        scrollView.scrollEnabled = YES;
    }
}


回答9:

It's possible to remove scrolling in vertical direction by setting the scrollView.contentSize height to the same value as scrollView.frame.size.height. Any overflowing content will be hidden. Same can of course be done to restrict vertical scrolling.