UIScrollView custom paging size

后端 未结 11 1491
走了就别回头了
走了就别回头了 2020-12-07 11:49

paging in UIScrollView is a great feature, what I need here is to set the paging to a smaller distance, for example I want my UIScrollView to page less size that the UIScrol

相关标签:
11条回答
  • 2020-12-07 12:19

    Adding gesture recognizers or other subviews and so on is silly. Just set the delegate for the scroll view an imlement on of the below :

    // This is for a vertical scrolling scroll view. 
    // Let's say you want it to snap to every 160 pixels :    
    
    - (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate
    {     
         int y = scrollView.contentOffset.y;
         int yOff = y % 160;
         if(yOff < 80)
              y -= yOff;
         else
              y += 160 - yOff;
    
         [scrollView setContentOffset:CGPointMake(scrollView.contentOffset.x, y) animated:YES];
    }
    
    // This is for a horizontal scrolling scroll view.
    // Let's say you want the same, to snap to every 160 pixels :
    
    - (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate
    {
         int x = scrollView.contentOffset.x;
         int xOff = x % 160;
         if(xOff < 80)
              x -= xOff;
         else
              x += 160 - xOff;
    
         [scrollView setContentOffset:CGPointMake(x, scrollView.contentOffset.y) animated:YES];
    }
    
    0 讨论(0)
  • 2020-12-07 12:22

    There is a UIScrollView delegate method you can use. Set your class as the scroll view's delegate, and then implement the following:

    - (void)scrollViewWillEndDragging:(UIScrollView *)scrollView withVelocity:(CGPoint)velocity targetContentOffset:(inout CGPoint *)targetContentOffset
    {
        CGFloat kMaxIndex = 23;
        CGFloat targetX = scrollView.contentOffset.x + velocity.x * 60.0;
        CGFloat targetIndex = 0.0;
        if (velocity.x > 0) {
            targetIndex = ceil(targetX / (kCellWidth + kCellSpacing));
        } else if (velocity.x == 0) {
            targetIndex = round(targetX / (kCellWidth + kCellSpacing));
        } else if (velocity.x < 0) {
            targetIndex = floor(targetX / (kCellWidth + kCellSpacing));
        }
        if (targetIndex < 0)
            targetIndex = 0;
        if (targetIndex > kMaxIndex)
            targetIndex = kMaxIndex;
        targetContentOffset->x = targetIndex * (kCellWidth + kCellSpacing);
        //scrollView.decelerationRate = UIScrollViewDecelerationRateFast;//uncomment this for faster paging
    }
    

    The velocity parameter is necessary to make sure the scrolling feels natural and doesn't end abruptly when a touch ends with your finger still moving. The cell width and cell spacing are the page width and spacing between pages in your view. In this case, I'm using a UICollectionView.

    0 讨论(0)
  • 2020-12-07 12:22
    1. Change your scrollView size to the page size you want
    2. Set your scroll.clipsToBounds = NO
    3. Create a UIView subclass (e.g HackClipView) and override the hitTest:withEvent: method

      -(UIView *) hitTest:(CGPoint) point withEvent:(UIEvent *)event
      {     
          UIView* child = [super hitTest:point withEvent:event]; 
          if (child == self && self.subviews.count > 0)  
          {
              return self.subviews[0];
          }
          return child;
      }
      
    4. Set the HackClipView.clipsToBounds = YES

    5. Put your scrollView in this HackClipView (with the total scrolling size you want)

    See this answer for more details

    Update: As stated in lucius answer you can now implement the UIScollViewDelegate protocol and use the - (void)scrollViewWillEndDragging:(UIScrollView *)scrollView withVelocity:(CGPoint)velocity targetContentOffset:(inout CGPoint *)targetContentOffset method. As the targetContentOffset is a pointer. Using this method will not guarantee you the same result with scroll view pages as the user can scroll through many pages at once. But setting the descelerationRate to fast will almost give you the same result

    0 讨论(0)
  • 2020-12-07 12:25

    I had the same problem so I have made a custom UIScrollView. It's available on Github now because when I searched I didn't find any solutions like this. Enjoy! https://github.com/MartinMetselaar/MMCPSScrollView

    MMCPSScrollView* scrollView = [[MMCPSScrollView alloc] initWithFrame:self.view.bounds];
    [scrollView setType:MMCPSScrollVertical];
    [scrollView setPageHeight:250];
    [scrollView setPageSize:2];
    [self.view addSubview:scrollView];
    

    If you have any further questions about this component, just ask.

    0 讨论(0)
  • 2020-12-07 12:26

    Set the contentOffset in -(void)scrollViewDidScroll:(UIScrollView *)scrollView method.

    Also refer to UIScrollViewDelegate refernces

    0 讨论(0)
提交回复
热议问题