电影项目 (四)

一.子类化UICollectionViewFlowLayout:

代码如下 :

//
//  LargeCollectionViewLayout.m
//  Movie 2.0
//
//  Created by mac1 on 15/10/12.
//  Copyright (c) 2015年 www.iphonetrain.com. All rights reserved.
//

#import "LargeCollectionViewLayout.h"
#import "Common.h"

@implementation LargeCollectionViewLayout


- (id)init{

    self = [super init];
    if (self) {
        
        //布局信息
        self.itemSize =
        CGSizeMake(kScreenWidth * 0.75,
                   kScreenHeight - kNavigationBarHeight - kTabBarHeight -
                   kMovieHeaderViewHeight - kMovieFooterViewHeight);
        //上下分别留出来其他两个部分的位置,
        //减去距离CollectionView顶部和底部空余的空间
        
        // flowLayout.minimumInteritemSpacing = 0;
        self.minimumLineSpacing = 0;
        
        self.scrollDirection = UICollectionViewScrollDirectionHorizontal;

    }
    
    return self;
    
}

 

二.设置放大缩小:

 

 

//当bounds发生变化时,是否继续布局
- (BOOL)shouldInvalidateLayoutForBoundsChange:(CGRect)newBounds{
    
    return YES;
    
}

//设置一定范围内,CollectionView元素(Cell、装饰视图、补充视图)的布局属性
- (NSArray *)layoutAttributesForElementsInRect:(CGRect)rect {
    
    //先获取rect范围内这些元素,之前的布局信息
    NSArray *array = [super layoutAttributesForElementsInRect:rect];
    
    //可见的范围
    CGRect visibleRect;
    visibleRect.origin = self.collectionView.contentOffset;
    visibleRect.size = self.collectionView.bounds.size;
    
    //数组中保存的所有的元素的布局信息 UICollectionViewLayoutAttributes
    for (UICollectionViewLayoutAttributes *attribute in array) {
        // NSLog(@"att = %@", attribute);
        // attribute.transform = CGAffineTransformMakeScale(0.5, 0.5);
        
        //判断两个rect是否有交集,如果单元格frame和rect有交叉,修改transform
        if (CGRectIntersectsRect(attribute.frame, rect)) {
            
            // 单元格移动的距离 = 可见范围的中心 - 单元格frame的中心
            // CGRectGetMidX(rect)获取rect的中心点的x坐标
            CGFloat distance = CGRectGetMidX(visibleRect) - attribute.center.x;
            
            CGFloat disScale = distance / 200;
            
            if (ABS(distance) < 200) { // ABS(a)取a的绝对值
                //放大的比例
                CGFloat scale = 1 + 0.1 * (1 - ABS(disScale));
                
                // transform3D 是三维坐标系统的变化
                // CATransform3DMakeScale 分别对三个坐标轴进行缩放
                // sz参数是第三个坐标轴,垂直于屏幕为坐标轴
                attribute.transform3D = CATransform3DMakeScale(scale, scale, 1);
                
                // zIndex是z轴方向上的坐标值
                attribute.zIndex = 1;
            }
        }
    }
    
    //将修改后的布局信息返回
    return array;
}


//返回一个目标偏移量(最终停留的位置)
- (CGPoint)targetContentOffsetForProposedContentOffset:(CGPoint)proposedContentOffset withScrollingVelocity:(CGPoint)velocity{
    
    //ProposedContentOffset 如果没有对齐的效果本来应该停留的位置
    
    //找屏幕的中心,取到所有单元格,单元格的中心和屏幕的中心进行比较,找到最接近屏幕中心的单元格
    //根据这个单元格,去推算目标偏移量
    
    CGFloat horizontalCenter = (self.collectionView.bounds.size.width / 2) + proposedContentOffset.x;
    //指定当前显示的范围
    CGRect rect = CGRectMake(proposedContentOffset.x, 0, self.collectionView.bounds.size.width, self.collectionView.bounds.size.height);
    NSArray *array = [super layoutAttributesForElementsInRect:rect];
    
    CGFloat minimumValue = MAXFLOAT; //单元格和屏幕中心差值的最小值
    
    for (UICollectionViewLayoutAttributes *attribute in array) {
        CGFloat itemCenter = attribute.center.x;
        if (ABS(itemCenter - horizontalCenter) < ABS(minimumValue)) {
            minimumValue = itemCenter - horizontalCenter; //最终有一个最接近屏幕中心的单元格
        }
    }
    
    //之前偏移量 + (单元格的中心距离当前停留的中心的距离)
    CGPoint targetContentOffset = CGPointMake(proposedContentOffset.x + minimumValue, proposedContentOffset.y);
    return targetContentOffset;
}

 

posted on 2015-10-12 20:48  玉思盈蝶  阅读(168)  评论(0编辑  收藏  举报

导航