ios 仿android gallery控件
2017-07-04 18:56
295 查看
ios 上没有发现与android gallery类似的控件,因为在项目上须要使用到.採用UICollectionView实现
ViewController.m
LineLayout.m
ImageCell.m
ViewController.m
#import "ViewController.h" #import "ImageCell.h" #import "LineLayout.h" @interface ViewController () <UICollectionViewDataSource, UICollectionViewDelegate> @property (nonatomic, strong) NSMutableArray *images; @property (nonatomic, weak) UICollectionView *collectionView; @end @implementation ViewController static NSString *const ID = @"image"; - (NSMutableArray *)images { if (!_images) { self.images = [[NSMutableArray alloc] init]; for (int i = 1; i<=20; i++) { [self.images addObject:[NSString stringWithFormat:@"%d", i]]; } } return _images; } - (void)viewDidLoad { [super viewDidLoad]; CGFloat w = self.view.frame.size.width; CGRect rect = CGRectMake(0, 100, w, 200); UICollectionView *collectionView = [[UICollectionView alloc] initWithFrame:rect collectionViewLayout:[[LineLayout alloc] init]]; collectionView.dataSource = self; collectionView.delegate = self; [collectionView registerNib:[UINib nibWithNibName:@"ImageCell" bundle:nil] forCellWithReuseIdentifier:ID]; [self.view addSubview:collectionView]; self.collectionView = collectionView; // collectionViewLayout : // UICollectionViewLayout // UICollectionViewFlowLayout } - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event { if ([self.collectionView.collectionViewLayout isKindOfClass:[LineLayout class]]) { [self.collectionView setCollectionViewLayout:[[UICollectionViewFlowLayout alloc] init] animated:YES]; } else { [self.collectionView setCollectionViewLayout:[[LineLayout alloc] init] animated:YES]; } } #pragma mark - <UICollectionViewDataSource> - (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section { return self.images.count; } - (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath { ImageCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:ID forIndexPath:indexPath]; cell.image = self.images[indexPath.item]; return cell; } - (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath { // 删除模型数据 [self.images removeObjectAtIndex:indexPath.item]; // 删UI(刷新UI) [collectionView deleteItemsAtIndexPaths:@[indexPath]]; } @end
LineLayout.m
#import "LineLayout.h" static const CGFloat ItemWH = 100; @implementation LineLayout - (instancetype)init { if (self = [super init]) { } return self; } /** * 仅仅要显示的边界发生改变就又一次布局: 内部会又一次调用prepareLayout和layoutAttributesForElementsInRect方法获得全部cell的布局属性 */ - (BOOL)shouldInvalidateLayoutForBoundsChange:(CGRect)newBounds { return YES; } /** * 用来设置collectionView停止滚动那一刻的位置 * * @param proposedContentOffset 原本collectionView停止滚动那一刻的位置 * @param velocity 滚动速度 */ - (CGPoint)targetContentOffsetForProposedContentOffset:(CGPoint)proposedContentOffset withScrollingVelocity:(CGPoint)velocity { // 1.计算出scrollView最后会停留的范围 CGRect lastRect; lastRect.origin = proposedContentOffset; lastRect.size = self.collectionView.frame.size; // 计算屏幕最中间的x CGFloat centerX = proposedContentOffset.x + self.collectionView.frame.size.width * 0.5; // 2.取出这个范围内的全部属性 NSArray *array = [self layoutAttributesForElementsInRect:lastRect]; // 3.遍历全部属性 CGFloat adjustOffsetX = MAXFLOAT; for (UICollectionViewLayoutAttributes *attrs in array) { if (ABS(attrs.center.x - centerX) < ABS(adjustOffsetX)) { adjustOffsetX = attrs.center.x - centerX; } } return CGPointMake(proposedContentOffset.x + adjustOffsetX, proposedContentOffset.y); } /** * 一些初始化工作最好在这里实现 */ - (void)prepareLayout { [super prepareLayout]; // 每个cell的尺寸 self.itemSize = CGSizeMake(ItemWH, ItemWH); CGFloat inset = (self.collectionView.frame.size.width - HMItemWH) * 0.5; self.sectionInset = UIEdgeInsetsMake(0, inset, 0, inset); // 设置水平滚动 self.scrollDirection = UICollectionViewScrollDirectionHorizontal; self.minimumLineSpacing = ItemWH * 0.7; // 每个cell(item)都有自己的UICollectionViewLayoutAttributes // 每个indexPath都有自己的UICollectionViewLayoutAttributes } /** 有效距离:当item的中间x距离屏幕的中间x在HMActiveDistance以内,才会開始放大, 其他情况都是缩小 */ static CGFloat const ActiveDistance = 150; /** 缩放因素: 值越大, item就会越大 */ static CGFloat const ScaleFactor = 0.6; - (NSArray *)layoutAttributesForElementsInRect:(CGRect)rect { // 0.计算可见的矩形框 CGRect visiableRect; visiableRect.size = self.collectionView.frame.size; visiableRect.origin = self.collectionView.contentOffset; // 1.取得默认的cell的UICollectionViewLayoutAttributes NSArray *array = [super layoutAttributesForElementsInRect:rect]; // 计算屏幕最中间的x CGFloat centerX = self.collectionView.contentOffset.x + self.collectionView.frame.size.width * 0.5; // 2.遍历全部的布局属性 for (UICollectionViewLayoutAttributes *attrs in array) { // 假设不在屏幕上,直接跳过 if (!CGRectIntersectsRect(visiableRect, attrs.frame)) continue; // 每个item的中点x CGFloat itemCenterX = attrs.center.x; // 差距越小, 缩放比例越大 // 依据跟屏幕最中间的距离计算缩放比例 CGFloat scale = 1 + ScaleFactor * (1 - (ABS(itemCenterX - centerX) / ActiveDistance)); attrs.transform = CGAffineTransformMakeScale(scale, scale); } return array; } @end
ImageCell.m
#import "ImageCell.h" @interface ImageCell() @property (weak, nonatomic) IBOutlet UIImageView *imageView; @end @implementation ImageCell - (void)awakeFromNib { self.imageView.layer.borderWidth = 3; self.imageView.layer.borderColor = [UIColor whiteColor].CGColor; self.imageView.layer.cornerRadius = 3; self.imageView.clipsToBounds = YES; } - (void)setImage:(NSString *)image { _image = [image copy]; self.imageView.image = [UIImage imageNamed:image]; } @end
相关文章推荐
- ios 仿android gallery控件
- Android 控件之Gallery图片集
- Android控件之Gallery探究
- Android自定义Gallery中子控件OnClick事件无响应
- Android控件开发之Gallery3D效果
- 系出名门Android(8) - 控件(View)之TextSwitcher, Gallery, ImageSwitcher, GridView, ListView, ExpandableList
- Android系列之浅谈AndroidGallery控件使用方法详解
- 在iOS上实现Android风格的控件Toast
- [开源]在iOS上实现Android风格的控件Toast 推荐
- Android Gallery控件使用方法详解
- android常用控件二 gallery
- Android控件开发之Gallery
- android Gallery控件与BaseAdapter适配器
- Android之Gallery控件使用
- 系出名门Android(8) - 控件(View)之TextSwitcher, Gallery, ImageSwitcher, GridView, ListView, ExpandableList
- Android控件系列之相册Gallery&Adapter适配器入门&控件缩放动画入门
- Android 控件之Gallery和ImageSwitcher图片切换器
- Android控件Gallery3D效果
- 系出名门Android(8) - 控件(View)之TextSwitcher, Gallery, ImageSwitcher, GridView, ListView
- [开源]在iOS上实现Android风格的控件Toast