UICollectionView实现新特性及滑动相册

(一)CollectionViewController:和TableViewController一样,也可以有header和footer。

(二)新特性:一般app的新特性一般也是由CollectionView来实现。其实UIScrollView也可以实现。

  回家吃饭APP新特性模拟实现:

  主要代码:

     self.collectionView?.backgroundColor = UIColor.whiteColor()
self.collectionView
!.registerClass(SGCollectionViewCell.self, forCellWithReuseIdentifier: reuseIdentifier) let layout = collectionViewLayout as! UICollectionViewFlowLayout layout.itemSize = view.bounds.size layout.minimumLineSpacing = 0 layout.scrollDirection = .Horizontal collectionView?.pagingEnabled = false collectionView?.showsHorizontalScrollIndicator = false collectionView?.bounces = false

注意:如上collectionView的属性其实都是UIScrollView的。

  大致效果:

  

(三)实现横向照片相册查看功能

  效果图:

  实现分析:

    (1)此时需要进行更多的设置,需要对layout进行自定义,在preparelayout中进行操作。此方法在一开始布局和刷新布局的时候会进行调用。

    (2)在自定义布局中通过计算拿到应该放大的item和缩小的item。改变他们的transform。

    (3)刷新item。

    主要代码:

    // 准备布局和刷新布局的时候调用,在这里进行设置
    override func prepareLayout() {
        
        // 改变item的size
        
        super.prepareLayout()
        
        // 设置大小
        itemSize = CGSizeMake((collectionView?.frame.size.height)! * 0.6, (collectionView?.frame.size.width)! * 0.6)
        // 设置滚动方向
        scrollDirection = .Horizontal
        
        sectionInset = UIEdgeInsetsMake(0, ((collectionView?.frame.size.width)! - itemSize.width) / 2, 0, ((collectionView?.frame.size.width)! - itemSize.width) / 2)
        
        
        
    }
override func layoutAttributesForElementsInRect(rect: CGRect) -> [UICollectionViewLayoutAttributes]? {
        
        
        // 可以拿到当前 可以看到的cell加上前后cell的各个LayoutAttributes属性
        let attrArray = super.layoutAttributesForElementsInRect(rect)
        
        // 当前可见cell是两个,一共显示四个
        print(attrArray)
        
        // 计算屏幕中心点(整个collectionView是横屏移动的,中心点应该等于自己的宽度的一半 + 偏移量)
        let centerScreen = collectionView!.frame.size.width / 2 + collectionView!.contentOffset.x
        
        for arris in attrArray! {
            
            // 拿到每个item的中心点
            let centerItem = arris.center.x
            
            // 计算偏移量的绝对值
            let offSet = abs(centerScreen - centerItem)
            
            // 通过间隔, 计算一个 放大系数
            // (deltaMargin / 250) 计算出一个系数
            let scalRatio =  1.2 - (offSet / (self.collectionView!.frame.size.width/2 + arris.size.width));
            
            // 计算transform
            arris.transform = CGAffineTransformMakeScale(scalRatio, scalRatio)
 
        }

        return attrArray
    }
    // MARK: - 在滚动的时候刷新布局
    override func shouldInvalidateLayoutForBoundsChange(newBounds: CGRect) -> Bool {
        return true
    }
    
    // 拖动的时候 ,返回CGPoint,让最中央的图片如果滑动不是太多,就停留在中点
    override func targetContentOffsetForProposedContentOffset(proposedContentOffset: CGPoint) -> CGPoint {
        
        // 1. 计算屏幕的中心点
        let screenCenterX = collectionView!.frame.size.width/2 + proposedContentOffset.x;
        
        
        // 2. 拿到当前的可见rect
        var visibleRect = CGRectZero;
        
        visibleRect.size = collectionView!.frame.size;
        visibleRect.origin = proposedContentOffset;
        
        // 3. 获取可见范围内的cell
        let attributes = super.layoutAttributesForElementsInRect(visibleRect);
        
        // 4. 找到最小距离(屏幕中心点 和  cell 中心点之间的差值)
        var minMargin = CGFloat(MAXFLOAT);
        
        for att in attributes! {
            // 计算差值
            let deltaMargin = att.center.x - screenCenterX ;
            
            if (abs(CGFloat(minMargin)) > abs(deltaMargin)) {
                
                minMargin = deltaMargin;
            }
        }
        
        return CGPointMake(proposedContentOffset.x + minMargin, proposedContentOffset.y);
    }

 

posted @ 2016-09-02 15:40  三更小新  阅读(462)  评论(0编辑  收藏  举报