开发者

UIScrollView disable scrolling in just one direction?

开发者 https://www.devze.com 2023-02-19 01:23 出处:网络
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 v

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开发者_如何学C 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


Turns out a simple solution was actually possible and easy:

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


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


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


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


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


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.


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.


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.


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.


Turn Off the auto layout. I had the same issues only fixed after disabling auto layout in the content view. Xcode 11 . Automatic -> Translate Masks to Constraints

0

精彩评论

暂无评论...
验证码 换一张
取 消