美文网首页
CollectionView pageEnable 自定义实现

CollectionView pageEnable 自定义实现

作者: CodingTom | 来源:发表于2022-03-01 17:33 被阅读0次

方式一 (实现scrollView的代理较为通用)

- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView
{
         self.start = scrollView.contentOffset.x;
}
- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate
{
       self.end = scrollView.contentOffset.x;

        NSInteger index = self.currentSelectedIndex;
        if (self.end - self.start >= 20) {
            index++;
        } else if (self.start - self.end >= 20) {
            index--;
        }

        if (index < 0) {
            index = 0;
        }
        if (index >= self.dataSource.count) {
            index = self.dataSource.count - 1;
        }
        self.currentSelectedIndex = index;
        dispatch_async(dispatch_get_main_queue(), ^{
            [self.centerCollectionView scrollToItemAtIndexPath:[NSIndexPath indexPathForItem:index inSection:0] atScrollPosition:UICollectionViewScrollPositionCenteredHorizontally animated:YES];
        });
}

方式二 (自定义UICollectionViewFlowLayout)


class TestLayout: UICollectionViewFlowLayout {
    var stepSpace:CGFloat {
        return self.itemSize.width + self.minimumLineSpacing
    }
    var lastPosition:CGPoint = .zero
    
    override func prepare() {
        super.prepare()
        self.collectionView?.decelerationRate = .fast
    }
    override func targetContentOffset(forProposedContentOffset proposedContentOffset: CGPoint, withScrollingVelocity velocity: CGPoint) -> CGPoint {
        
        let move =  CGFloat(abs(Int32(self.lastPosition.x - proposedContentOffset.x)))
        
        let factor = move / self.stepSpace > 1
        
        let trigger = !(-0.3...0.3).contains(Double(velocity.x))
        
        
        var offset = proposedContentOffset
        
        switch velocity.x {
        // 左滑
        case let x where x > 0 && trigger && !factor:
            offset.x = stepSpace * CGFloat(ceil(Double(proposedContentOffset.x / stepSpace)))
        case let x where x > 0 && trigger && factor:
            offset.x = lastPosition.x + stepSpace
        // 右滑
        case let x where x < 0 && trigger && !factor:
            offset.x = stepSpace * CGFloat(floor(Double(proposedContentOffset.x / stepSpace)))
        case let x where x < 0 && trigger && factor:
            offset.x = lastPosition.x - stepSpace
        default:
            offset = lastPosition
            break
        }
        
        lastPosition = offset
        
        return offset
    }
}

第三种 修改layout的_setInterpageSpacing的值

OC

  if ([self.collectionView respondsToSelector:NSSelectorFromString(@"_setInterpageSpacing:")]) {
        ((void(*)(id,SEL,CGSize))objc_msgSend)(self.collectionView,NSSelectorFromString(@"_setInterpageSpacing:"),CGSizeMake(-(self.hzj_short), 0));
    }
extension UICollectionViewFlowLayout {
    
    private static var _hzj_short = "_hzj_short"
    
    /**
     *相对于collectionView的尺寸,在滑动方向减少的距离
     *比如collectionView的尺寸(200,300),水平滑动,若想滑动160后边停止,则设置hzj_short=(200-160)=40
     */
    var hzj_short:CGFloat? {
        set{
            objc_setAssociatedObject(self, &UICollectionViewFlowLayout._hzj_short, newValue, .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
        }
        get{
            return objc_getAssociatedObject(self, &UICollectionViewFlowLayout._hzj_short) as? CGFloat
        }
    }
    open override func prepare() {
        super.prepare()
        if let short = self.hzj_short {
            self.collectionView?.decelerationRate = .fast
            //使用kvc
            if ((self.collectionView?.value(forKey: "interpageSpacing") as? CGSize) != nil) {
                let size = self.scrollDirection == .horizontal ? CGSize(width: -short,height: 0) : CGSize(width: 0 ,height: -short)
                self.collectionView?.setValue(size, forKey: "interpageSpacing")
            }
            if ((self.collectionView?.value(forKey: "pagingOrigin") as? CGPoint) != nil) {
                self.collectionView?.setValue(CGPoint.zero, forKey: "pagingOrigin")
            }
        }
    }
}

参考资料

https://www.jianshu.com/p/7093c04b90fe

https://www.jianshu.com/p/e62dd10bf17c

UICollectionView自定义分页滑动宽度(高度)

相关文章

网友评论

      本文标题:CollectionView pageEnable 自定义实现

      本文链接:https://www.haomeiwen.com/subject/qrfjrrtx.html