实现过程
- 创建两个UICollectionView分别放置大图和缩略图
- 实现大图和缩略图的联动
- 实现当前展示的大图对应的缩略图放大效果
实现原理
- 创建collectionView非常简单,只要正常创建就好,值得注意的是:由于需要当前展示的图片的缩略图始终保持在屏幕中间位置,所以在创建缩略图的collectionView的时候需要对collection View设置好便宜量。
- (UIEdgeInsets)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout insetForSectionAtIndex:(NSInteger)section{
return UIEdgeInsetsMake(0, (kScreenWidth - _itemWidth)/2, 0, (kScreenWidth - _itemWidth)/2);
} - 实现上下联动通过两个block来实现
-(void)collectionViewDidScrollWithScrollBlock:(DidScrollBlock)didScrollBlcok;
-(void)collectionViewDidScrollWithScrollBlock:(IndexScrollBlock)didScrollBlcok;
- 实现当前显示缩略图放大通过设置collectionView的UICollectionViewFlowLayout实现
IndexFlow *flowLayout = [[IndexFlow alloc] init];
self = [super initWithFrame:frame collectionViewLayout:flowLayout];
部分实现代码
- (void)collectionViewDidScrollWithScrollBlock:(DidScrollBlock)didScrollBlcok{
self.didScrollBlcok = didScrollBlcok;
}
- (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer{
self.shouldDid = YES;
return YES;
}
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView{
self.shouldDid = NO;
}
- (void)scrollViewDidScroll:(UIScrollView *)scrollView{
if (self.shouldDid) {
if (self.didScrollBlcok) {
self.didScrollBlcok(self);
}
}
}
- (UIEdgeInsets)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout insetForSectionAtIndex:(NSInteger)section{
return UIEdgeInsetsMake(0, (kScreenWidth - _itemWidth)/2, 0, (kScreenWidth - _itemWidth)/2);
}
- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath{
return CGSizeMake(_itemWidth, self.height);
}
- (CGFloat)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout minimumLineSpacingForSectionAtIndex:(NSInteger)section{
return _minLineSpacing;
}
缩略图放大实现代码
- (BOOL)shouldInvalidateLayoutForBoundsChange:(CGRect)oldBounds
{
return YES;
}
-(NSArray*)layoutAttributesForElementsInRect:(CGRect)rect
{
// 取出所有元素
NSArray *array = [super layoutAttributesForElementsInRect:rect];
// 可视区域
CGRect visibleRect;
visibleRect.origin = self.collectionView.contentOffset;
visibleRect.size = self.collectionView.bounds.size;
for (UICollectionViewLayoutAttributes *attribute in array) {
CGFloat distance = CGRectGetMidX(visibleRect) - attribute.center.x;
CGFloat normalizedDistance = distance / ACTIVE_DISTANCE;
if (ABS(distance) < ACTIVE_DISTANCE) {
CGFloat zoom = 1 + ZOOM_FACTOR*(1 - ABS(normalizedDistance));
attribute.transform3D = CATransform3DMakeScale(zoom, zoom, 1.0);
attribute.zIndex = 1;
}
}
return array;
}
/**
* 设置collectionView停止滚动那一刻的位置
*
* @param proposedContentOffset 原本collectionView停止滚动那一刻的位置
* @param velocity 速度
*
* @return 最终的位置
*/
- (CGPoint)targetContentOffsetForProposedContentOffset:(CGPoint)proposedContentOffset withScrollingVelocity:(CGPoint)velocity
{
CGFloat offsetAdjustment = MAXFLOAT;
CGFloat horizontalCenter = proposedContentOffset.x + (CGRectGetWidth(self.collectionView.bounds) / 2.0);
// 停止时刻的可视区域
CGRect targetRect = CGRectMake(proposedContentOffset.x, 0.0, self.collectionView.bounds.size.width, self.collectionView.bounds.size.height);
NSArray* array = [super layoutAttributesForElementsInRect:targetRect];
for (UICollectionViewLayoutAttributes* layoutAttributes in array) {
CGFloat itemHorizontalCenter = layoutAttributes.center.x;
if (ABS(itemHorizontalCenter - horizontalCenter) < ABS(offsetAdjustment)) {
offsetAdjustment = itemHorizontalCenter - horizontalCenter;
}
}
return CGPointMake(proposedContentOffset.x + offsetAdjustment, proposedContentOffset.y);
}