UIScrollView Custom Paging

2019-01-14 17:09发布

My question has to do with a custom form of paging which I am trying to do with a scroller, and this is easier to visualise if you first consider the type of scroll view implemented in a slot machine.

So say my UIScrollView has a width of 100 pixels. Assume it contains 3 inner views, each with a width of 30 pixels, such that they are separated by a width of 3 pixels. The type of paging which I would like to achieve, is such that each page is one of my views (30 pixels), and not the whole width of the scroll view.

I know that usually, if the view takes up the whole width of the scroll view, and paging is enabled then everything works. However, in my custom paging, I also want surrounding views in the scroll view to be visible as well.

How would I do this?

7条回答
祖国的老花朵
2楼-- · 2019-01-14 17:42

After a couple of days of researching and troubleshooting i came up with something that works for me!

First you need to subclass the view that the scrollview is in and override this method with the following:

    -(UIView*)hitTest:(CGPoint)point withEvent:(UIEvent*)event {
          UIView* child = nil;
          if ((child = [super hitTest:point withEvent:event]) == self)
                 return (UIView *)_calloutCell;
           return child;
    }

Then all the magic happens in the scrollview delegate methods

    -(void)scrollViewWillBeginDragging:(UIScrollView *)scrollView {
            //_lastOffset is declared in the header file
            //@property (nonatomic) CGPoint lastOffset;
            _lastOffset = scrollView.contentOffset;
     }

    - (void)scrollViewWillEndDragging:(UIScrollView *)scrollView withVelocity:(CGPoint)velocity targetContentOffset:(inout CGPoint *)targetContentOffset {

            CGPoint currentOffset = scrollView.contentOffset;
            CGPoint newOffset = CGPointZero;

            if (_lastOffset.x < currentOffset.x) {
                // right to left
                newOffset.x = _lastOffset.x + 298;
            }
            else {
                 // left to right
                 newOffset.x = _lastOffset.x - 298;
            }

            [UIView beginAnimations:nil context:NULL];
            [UIView setAnimationDuration:0.5];
            [UIView setAnimationDelay:0.0f];

            targetContentOffset->x = newOffset.x;
            [UIView commitAnimations];

      }

You also need to set the scrollview's deceleration rate. I did it in ViewDidLoad

    [self.scrollView setDecelerationRate:UIScrollViewDecelerationRateFast];
查看更多
登录 后发表回答