zoukankan      html  css  js  c++  java
  • 自定义UICollectionViewFlowLayout实现横向滚动时,离中心点越近,item越大,离中心店越远,item越小的效果

    控制器代码

    class ViewController: UIViewController {
        
        override func viewDidLoad() {
            super.viewDidLoad()
            view.addSubview(collectionView)
        }
     
        lazy var collectionView:UICollectionView = {
            let layout = Layer()
            layout.itemSize = CGSize( 160, height: 160)
            layout.scrollDirection = .horizontal
            let margin = (UIScreen.main.bounds.size.width - 160) * 0.5
            layout.sectionInset = UIEdgeInsets(top: 0, left: margin, bottom: 0, right: margin)
            layout.minimumLineSpacing = 50
           
            let collectionView = UICollectionView(frame: CGRect(x: 0, y: 200,  UIScreen.main.bounds.size.width, height: 200), collectionViewLayout: layout)
            collectionView.backgroundColor = .purple
            collectionView.delegate = self
            collectionView.dataSource = self
            collectionView.register(CollectionViewCell.self, forCellWithReuseIdentifier: "reuseId")
            return collectionView
        }()
    }
    

      自定义UICollectionViewFlowLayout

    class Layer: UICollectionViewFlowLayout {
        /**
         什么时候调用:collectionView第一次布局的时候调用  还有刷新的时候调用
         有什么作用:计算cell 的布局  条件:cell 位置固定不变的时候
         */
    //    open override func prepare(){
    //        super.prepare()
    //        print("调用")
    //    }
    
        /**
         UICollectionViewLayoutAttributes 确定cell的尺寸的
         一个 UICollectionViewLayoutAttributes 对象对应这一个cell
         是要拿到这个类  就相当于拿到cell
         */
        //作用:返回cell 的尺寸
        open override func layoutAttributesForElements(in rect: CGRect) -> [UICollectionViewLayoutAttributes]?{
    //        print(rect)
            //1.获取当前显示的区域
            let attrs = super.layoutAttributesForElements(in: self.collectionView?.bounds ?? CGRect.zero)
    //        print(attrs)
           
            //2.获取当前显示的cell 的布局
            // 效果: 越靠近中心点就越大
            if let attrs  = attrs  {
                for attr in attrs {
                    //2.1求cell 与中心点的距离
                    let margin = abs((attr.center.x - (self.collectionView?.contentOffset.x ?? 0) - ((self.collectionView?.frame.size.width ?? 0) * 0.5)))
                    //2.2计算比例
                    let scale = 1 - (margin / ((self.collectionView?.frame.size.width ?? 0) * 0.5) * 0.25)
                    attr.transform = CGAffineTransform(scaleX: scale, y: scale)
                }
            }
            return attrs
        }
        
        /**
         在滚动collectionView 的时候是否允许布局
         返回YES 每次都会刷新布局
         */
        override func shouldInvalidateLayout(forBoundsChange newBounds: CGRect) -> Bool {
            return true
        }
        
        /**
         什么时候调用: 用户手指松开的时候
         作用:确定最终偏移量
         */
        override func targetContentOffset(forProposedContentOffset proposedContentOffset: CGPoint, withScrollingVelocity velocity: CGPoint) -> CGPoint {
            print("确定偏移量")
            //最终偏移量 是否等于手指离开的偏移量(不等于)
            var finalPoint = super.targetContentOffset(forProposedContentOffset: proposedContentOffset, withScrollingVelocity: velocity)
    //        print(finalPoint, self.collectionView?.contentOffset)
            //1. 获取最终显示区域
            let collectionW = self.collectionView?.frame.size.width ?? 0
            let finalRect = CGRect(x: finalPoint.x, y: 0,  collectionW, height: CGFloat.greatestFiniteMagnitude)
            //获取最终显示cell
            let attrs = super.layoutAttributesForElements(in: finalRect)
            if let attrs  = attrs  {
                var minDetal = CGFloat.greatestFiniteMagnitude
                for attr in attrs {
                    var detal = (attr.center.x - (finalPoint.x ?? 0) - ((self.collectionView?.frame.size.width ?? 0) * 0.5))
                    //获取中心点的距离
                    if abs(detal) < abs(minDetal) {
                        minDetal = detal
                    }
                }
                finalPoint.x += minDetal
            }
            return finalPoint
        }
        
        /**
         计算collectionView 的滚动范围
         */
    //    override var collectionViewContentSize: CGSize{
    //        return super.collectionViewContentSize
    //    }
    }
    

      

      

      

  • 相关阅读:
    探讨变量的内存分配方式
    色彩之RGB和灰阶
    Perl语言:qw简写
    【转】位操作
    [转]Perl学习笔记
    Spaghetti code&Ravioli code&Lasagna code&Spaghetti with meatballs
    交叉编译lsusb
    GCC,LLVM,Clang编译器对比
    如何判断自己是否到了该辞职的时候
    Javascript Array和String的互转换。
  • 原文地址:https://www.cnblogs.com/dashengios/p/14887133.html
Copyright © 2011-2022 走看看