简体   繁体   中英

Swift - UIScrollView Jumps to first page instead scrolling to it

Is there a way to add circle scrolling to UIScrollView? For Example if the scroll reaches the last page the first page should be next and if scrolling back reaches the first page the last page should be next.

I have been trying using scrollViewDidScroll function however, when the scroll reaches the last page the view jumps back to first view instead of scrolling to it or add it next to it.

My code is:

func scrollViewDidScroll(scrollView: UIScrollView) {

        if (scrollView.contentOffset.x > scrollView.frame.size.width){
            scrollView.setContentOffset(CGPointZero, animated: true)
            //scrollView.scrollRectToVisible(CGRectMake(0, 0, 1, 1), animated: false)


        }

        if (scrollView.contentOffset.x < 0){
            scrollView.setContentOffset(CGPointMake(scrollView.frame.size.width,0.0), animated: true)
        }
    } 

Any Idea how to do this?

You're going to have to do a small amount of around the back work but it's nothing too arduous.

Seemingly displaying the first page of content to the right of the last isn't something that a scroll view can natively do. To fix that, you need to extend your contentSize by an extra screen to the right and duplicate your content.

That'll move you from having a content area that covers the range [0, end of last page) to [0, end of last page + 1). But you still want scrolling to be constrained to [0, last page), with offsets in the range [-1, 0] being mapped to [last page, last page + 1). So:

func scrollViewDidScroll(scrollView: UIScrollView) {

    let realContentWidth = scrollView.contentSize.width - scrollView.bounds.size.width

    scrollView.contentOffset.x = ((scrollView.contentOffset.x % realContentWidth) 
                                                    + realContentWidth) % realContentWidth;
} 

The logic on that modulo is:

  • if you start with content offset being a positive number then the inner % will map it to the correct range and the outer will cause the + to be a no-op; but
  • if you start with the content offset being a negative number then the inner % will leave it still negative but in (-realContentWidth, 0], so the + will then move it into the corresponding positive range with the outer % being a no-op.

(with the quick observation for Objective-C'ers: % is defined on floating point numbers in Swift; in Objective-C you'd use fmod in its place as % is defined only for integral arithmetic there)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM