电影项目 (四)
一.子类化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;
}
浙公网安备 33010602011771号