UIScrollView: paging horizontally, scrolling vertically?

后端 未结 20 1418
佛祖请我去吃肉
佛祖请我去吃肉 2020-11-27 09:09

How can I force a UIScrollView in which paging and scrolling are on to only move vertically or horizontally at a given moment?

My understanding is that

20条回答
  •  一向
    一向 (楼主)
    2020-11-27 09:33

    Here is my implementation of a paged UIScrollView that only allow orthogonal scrolls. Be sure to set pagingEnabled to YES.

    PagedOrthoScrollView.h

    @interface PagedOrthoScrollView : UIScrollView
    @end
    

    PagedOrthoScrollView.m

    #import "PagedOrthoScrollView.h"
    
    typedef enum {
      PagedOrthoScrollViewLockDirectionNone,
      PagedOrthoScrollViewLockDirectionVertical,
      PagedOrthoScrollViewLockDirectionHorizontal
    } PagedOrthoScrollViewLockDirection; 
    
    @interface PagedOrthoScrollView ()
    @property(nonatomic, assign) PagedOrthoScrollViewLockDirection dirLock;
    @property(nonatomic, assign) CGFloat valueLock;
    @end
    
    @implementation PagedOrthoScrollView
    @synthesize dirLock;
    @synthesize valueLock;
    
    - (id)initWithFrame:(CGRect)frame {
      self = [super initWithFrame:frame];
      if (self == nil) {
        return self;
      }
    
      self.dirLock = PagedOrthoScrollViewLockDirectionNone;
      self.valueLock = 0;
    
      return self;
    }
    
    - (void)setBounds:(CGRect)bounds {
      int mx, my;
    
      if (self.dirLock == PagedOrthoScrollViewLockDirectionNone) {
        // is on even page coordinates, set dir lock and lock value to closest page 
        mx = abs((int)CGRectGetMinX(bounds) % (int)CGRectGetWidth(self.bounds));
        if (mx != 0) {
          self.dirLock = PagedOrthoScrollViewLockDirectionHorizontal;
          self.valueLock = (round(CGRectGetMinY(bounds) / CGRectGetHeight(self.bounds)) *
                            CGRectGetHeight(self.bounds));
        } else {
          self.dirLock = PagedOrthoScrollViewLockDirectionVertical;
          self.valueLock = (round(CGRectGetMinX(bounds) / CGRectGetWidth(self.bounds)) *
                            CGRectGetWidth(self.bounds));
        }
    
        // show only possible scroll indicator
        self.showsVerticalScrollIndicator = dirLock == PagedOrthoScrollViewLockDirectionVertical;
        self.showsHorizontalScrollIndicator = dirLock == PagedOrthoScrollViewLockDirectionHorizontal;
      }
    
      if (self.dirLock == PagedOrthoScrollViewLockDirectionHorizontal) {
        bounds.origin.y = self.valueLock;
      } else {
        bounds.origin.x = self.valueLock;
      }
    
      mx = abs((int)CGRectGetMinX(bounds) % (int)CGRectGetWidth(self.bounds));
      my = abs((int)CGRectGetMinY(bounds) % (int)CGRectGetHeight(self.bounds));
    
      if (mx == 0 && my == 0) {
        // is on even page coordinates, reset lock
        self.dirLock = PagedOrthoScrollViewLockDirectionNone;
      }
    
      [super setBounds:bounds];
    }
    
    @end
    

提交回复
热议问题