UICollectionView 实现图片浏览效果

目录
  • 一、效果展示
  • 二、实现思路
  • 三、代码整理
    • 1、PhotoBrowseViewLayout
    • 2、PhotoBrowseCollectionViewCell
    • 3、CollectPhotoBrowseView
  • 四、总结与思考

一、效果展示

废话开篇:利用 UICollectionView 简单实现一个图片浏览效果。

二、实现思路

1.封装 UICollectionViewLayout ,实现内部 UICollectionViewCell 的布局。

UICollectionViewLayout 在封装瀑布流的时候会用到,而且担负着核心功能的实现。其实从另一个角度也可以把 UICollectionViewLayout 理解成“数据源”,这个数据不是 UI 的展示项,而是 UI 的尺寸项。在内部进行预计算 UICollectionViewCell 的 frame。

UICollectionView 是 UIScrollView的子类,只不过,它里面子控件通过“重用”机制实现了优化,一些复用的复杂逻辑还是扔给了系统处理。开发过程中只负责对 UICollectionViewLayout 什么时候需要干什么进行自定义即可。

2.获取 UICollectionView 目前可见的 cells,通过进行缩放、旋转变换实现一些简单的效果。

3、自定义 cell ,修改锚点属性。

三、代码整理

1、PhotoBrowseViewLayout

这里有一点需要注意的,在 UICollectionViewLayout 内部会进行计算每一个 cell 的 frame,在计算过程中,为了更好的展示旋转变换,cell 的锚点会修改到 (0.5,1),那么,为了保证 UI 展示不变,那么,就需要将 y 增加 cell 高度的一半。

#import "PhotoBrowseViewLayout.h"
@interface PhotoBrowseViewLayout()
@property(nonatomic,strong) NSMutableArray * attributeArray;
@property(nonatomic,assign) CGFloat cellWidth;
@property(nonatomic,assign) CGFloat cellHeight;
@property(nonatomic,assign) CGFloat sep;
@property(nonatomic,assign) int showCellNum;
@end
@implementation PhotoBrowseViewLayout
- (instancetype)init
{
    if (self = [super init]) {
        self.sep = 20;
        self.showCellNum = 2;
    }
    return self;
}
//计算cell的frame
- (UICollectionViewLayoutAttributes *)layoutAttributesForItemAtIndexPath:(NSIndexPath *)indexPath
{
    if (self.cellWidth == 0) {
        self.cellWidth = **self**.collectionView.frame.size.width * 2 / 3.0;
    }
    if (self.cellHeight == 0) {
        self.cellHeight = self.collectionView.frame.size.height;
    }
    CGFloat x = (self.cellWidth + self.sep) * indexPath.item;
    //这里y值需要进行如此设置,以抵抗cell修改锚点导致的UI错乱
    CGFloat y = self.collectionView.frame.size.height / 2.0;
    UICollectionViewLayoutAttributes *attrs = [UICollectionViewLayoutAttributes layoutAttributesForCellWithIndexPath:indexPath];
    attrs.frame = CGRectMake(x, y, self.cellWidth, self.cellHeight);
    return attrs;
}
//准备布局
- (void)prepareLayout
{
    [super prepareLayout];
    NSInteger count = [self.collectionView numberOfItemsInSection:0];
    for (int i = 0; i <count; i++) {
        UICollectionViewLayoutAttributes *attris = [self layoutAttributesForItemAtIndexPath:[NSIndexPath indexPathForRow:i inSection:0]];
        [self.attributeArray addObject:attris];
    }
}
//返回全部cell的布局集合
- (NSArray *)layoutAttributesForElementsInRect:(CGRect)rect
{
    return self.attributeArray;
}
//一次性提供UICollectionView 的 contentSize
- (CGSize)collectionViewContentSize
{
    NSInteger count = [self.collectionView numberOfItemsInSection:0];
    CGFloat maxWidth = count * self.cellWidth + (count - 1) * self.sep;
    return CGSizeMake(maxWidth, 0);
}
- (NSMutableArray *)attributeArray
{
    if (!_attributeArray) {
        _attributeArray = [[NSMutableArray alloc] init];
    }
    return _attributeArray;
}
@end

2、PhotoBrowseCollectionViewCell

这里主要是进行了锚点修改(0.5,1),代码很简单。

#import "PhotoBrowseCollectionViewCell.h"
@interface PhotoBrowseCollectionViewCell()
@property(nonatomic,strong) UIImageView * imageView;
@end
@implementation PhotoBrowseCollectionViewCell
- (instancetype)initWithFrame:(CGRect)frame
{
    if (self = [super initWithFrame:frame]) {
        //设置(0.5,1)锚点,以底部中点为轴旋转
        self.layer.anchorPoint = CGPointMake(0.5, 1);
        self.layer.masksToBounds = YES;
        self.layer.cornerRadius = 8;
    }
    return self;
}
- (void)setImage:(UIImage *)image
{
    self.imageView.image = image;
}
- (UIImageView *)imageView
{
    if (!_imageView) {
        _imageView = [[UIImageView alloc] init];
        _imageView.contentMode = UIViewContentModeScaleAspectFill;
        _imageView.backgroundColor = [UIColor groupTableViewBackgroundColor];
        [self.contentView addSubview:_imageView];
    }
    return _imageView;
}
- (void)layoutSubviews
{
    [super layoutSubviews];
    self.imageView.frame = **self**.contentView.bounds;
}
@end

3、CollectPhotoBrowseView

CollectPhotoBrowseView 负责进行一些 cell 的图形变换。

#import "CollectPhotoBrowseView.h"
#import "PhotoBrowseCollectionViewCell.h"
#import "PhotoBrowseViewLayout.h"
@interface CollectPhotoBrowseView()<UICollectionViewDelegate,UICollectionViewDataSource>
@property(nonatomic,strong) UICollectionView * photoCollectView;
@end
@implementation CollectPhotoBrowseView
- (instancetype)initWithFrame:(CGRect)frame
{
    if (self = [super initWithFrame:frame]) {
        [self makeUI];
    }
    return self;
}
- (void)makeUI{
    //设置自定义 UICollectionViewLayout
    PhotoBrowseViewLayout * photoBrowseViewLayout = [[PhotoBrowseViewLayout alloc] init];
    self.photoCollectView = [[UICollectionView alloc] initWithFrame:self.bounds collectionViewLayout:photoBrowseViewLayout];
    self.photoCollectView.delegate = self;
    self.photoCollectView.dataSource = self;
    [self.photoCollectView registerClass:[PhotoBrowseCollectionViewCell class] forCellWithReuseIdentifier:@"CELL"];
    self.photoCollectView.showsHorizontalScrollIndicator = NO;
    [self addSubview:self.photoCollectView];
    //执行一次可见cell的图形变换
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
        [self visibleCellTransform];
    });
}
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section
{
    return 20;
}
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
    PhotoBrowseCollectionViewCell * cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"CELL" forIndexPath:indexPath];
    [cell setImage: [UIImage imageNamed:[NSString stringWithFormat:@"fd%ld",indexPath.item % 3 + 1]]];
    return cell;
}
#pragma mark - 滚动进行图形变换
- (void)scrollViewDidScroll:(UIScrollView *)scrollView
{
    //滑动的时候,动态进行cell图形变换
    [self visibleCellTransform];
}
#pragma mark - 图形变化
- (void)visibleCellTransform
{
    //获取当前可见cell的indexPath集合
    NSArray * visibleItems =  [self.photoCollectView indexPathsForVisibleItems];
    //遍历动态进行图形变换
    for (NSIndexPath * visibleIndexPath in visibleItems) {
        UICollectionViewCell * visibleCell = [self.photoCollectView cellForItemAtIndexPath:visibleIndexPath];
        [self transformRotateWithView:visibleCell];
    }
}
//进行图形转换
- (void)transformRotateWithView:(UICollectionViewCell *)cell
{
    //获取cell在当前视图的位置
    CGRect rect = [cell convertRect:cell.bounds toView:self];
    //计算当前cell中轴线与中轴线的距离的比值
    float present = ((CGRectGetMidX(rect) - self.center.x) / (self.frame.size.width / 2.0));
    //根据位置设置选择角度
    CGFloat radian = (M_PI_2 / 15) * present;
    //图形角度变换
    CGAffineTransform transformRotate = CGAffineTransformIdentity;
    transformRotate = CGAffineTransformRotate(transformRotate, radian);
    //图形缩放变换
    CGAffineTransform transformScale = CGAffineTransformIdentity
    transformScale = CGAffineTransformScale(transformScale,1 -  0.2 *  fabs(present),1 - 0.2 * fabsf(present));
    //合并变换
    cell.transform = CGAffineTransformConcat(transformRotate,transformScale);
}
@end

四、总结与思考

UICollectionView 也是 View,只不过系统为了更好的服务于开发者,快速高效的实现某些开发场景,进行了封装与优化,将复杂的逻辑单独的封装成一个管理类,这里就是 UICollectionViewLayout,交给它去做一些固定且复杂的逻辑。所以,自定义复杂UI的时候,就需要将功能模块足够细化,以实现更好的代码衔接。

以上就是UICollectionView 实现图片浏览效果的详细内容,更多关于UICollectionView 图片浏览的资料请关注我们其它相关文章!

(0)

相关推荐

  • iOS UICollectionView实现标签选择器

    近来,在项目中需要实现一个类似兴趣标签的选择器.由于标签的文字长度不定,所以标签的显示长度就不定.为了实现效果,就使用了UICollectionView来实现了每行的标签数量不定.cell的宽度自适应的效果.先在此分享出来: 1.自适应UICollectionViewCell 这里只是在自适应UICollectionViewCell上放一个和UICollectionViewCell保持一样大小的按钮,当选中和取消选中时改变按钮的文字颜色和边框颜色: #pragma mark---标签cell @

  • iOS自定义UICollectionViewFlowLayout实现图片浏览效果

    以前瀑布流的时候使用过UICollectionView,但是那时使用的是系统自带的UICollectionViewFlowLayout布局,今天看文章,看到UICollectionViewFlowLayout自定义相关的东西,于是动手写了一个简单图片浏览的demo,熟练一些UICollectionViewFlowLayout自定义布局. #import <UIKit/UIKit.h> @interface JWCollectionViewFlowLayout : UICollectionVie

  • UIScrollView实现六棱柱图片浏览效果

    目录 一.效果展示 二.实现原理 三.代码 四.总结与思考 一.效果展示 废话开篇:利用 CATransform3D 图形变换及 UIScrollView 的一些方法实现一个六棱柱图片浏览效果 二.实现原理 1.在一个基础 View 上添加六棱柱的六个侧面视图. 2.调整六棱柱的各个侧面的旋转角度及z轴数值. 3.基础 View 放在 UIScrollView 上,通过监听 UIScrollView 的滑动来设置基础 View 的坐标x值与与y轴的旋转角度. 三.代码 创建 PhotoDrumB

  • ios uicollectionview实现横向滚动

    现在使用卡片效果的app很多,之前公司让实现一种卡片效果,就写了一篇关于实现卡片的文章.文章最后附有demo 实现上我选择了使用UICollectionView :用UICollectionViewFlowLayout来定制样式:下面看看具体实现 效果 实现上我选择了使用UICollectionView :用UICollectionViewFlowLayout来定制样式:下面看看具体实现 具体实现 1.ViViewController.m 代码实现 #import "ViewController

  • iOS UICollectionView实现卡片效果

    现在使用卡片效果的app很多,之前公司让实现一种卡片效果,就写了一篇关于实现卡片的文章.文章最后附有demo 实现上我选择了使用UICollectionView :用UICollectionViewFlowLayout来定制样式:下面看看具体实现 具体实现 1.创建UICollectionView - (void)createCollectionView { CGFloat pading = 0 * SCREEN_WIDTH/375; LHLeftCollocationView * layout

  • iOS UICollectionView实现横向滑动

    本文实例为大家分享了iOS UICollectionView实现横向滑动的具体代码,供大家参考,具体内容如下 UICollectionView的横向滚动,目前我使用在了显示输入框的输入历史上: // // SCVisitorInputAccessoryView.m // 访客通行录入页面--访客姓名输入历史的InputAccessory #import "SCInputAccessoryView.h" #import "SCInputAccessoryCell.h"

  • UICollectionView 实现图片浏览效果

    目录 一.效果展示 二.实现思路 三.代码整理 1.PhotoBrowseViewLayout 2.PhotoBrowseCollectionViewCell 3.CollectPhotoBrowseView 四.总结与思考 一.效果展示 废话开篇:利用 UICollectionView 简单实现一个图片浏览效果. 二.实现思路 1.封装 UICollectionViewLayout ,实现内部 UICollectionViewCell 的布局. UICollectionViewLayout 在

  • JavaScript仿百度图片浏览效果

    本文实例为大家分享了js图片浏览效果的具体代码,供大家参考,具体内容如下 在线地址:http://www.hui12.com/nbin/demo/imgskim/index.html https://nbin2008.github.io/demo/imgskim/index.html 效果图: index <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>仿

  • Android UI控件之Gallery实现拖动式图片浏览效果

    我们知道现在智能手机上都有这样一种功能,就是你在浏览图片的时候.不是硬性的点击按钮而是可以实现手指的拖动,划开效果.使用户具有更好的交互体验,不过这种效果是如何实现的呢? 在Android中是通过Gallery来实现拖动效果的. 通过Gallery可以实现各种各样的效果,此篇文章只是简要谈谈他的用法,至于后续的一些效果 有机会的时候做一个整理. 首先看看其简单实现吧!本次实例是通过选取图片实现类似设置背景的功能! 不过需要说明的是:图片不宜过大,否则容易内存溢出,android对大图片的支持不好

  • 推荐一个不错的图片浏览效果

    受那位WPSXXX的 IMG大于DIV 的启发 写的  有不足之处 如果有什么好的修改或建议 希望能给我一份copy 谢谢 sjx.saxon@gmail.com Map Image * {margin:0px auto;padding:0px;text-align:center;} * {font-size:9pt;font-family:Arial;} body {margin-top:20px;} body{-moz-user-select: none;-khtml-user-select

  • 来自国外的一款Js图片浏览效果

    效果图:测试代码: Js图片浏览器 play '; } this.m_mainviewer = this.container.firstChild.cloneNode(true); this.bind(); this.start(); }, writeCanvas : function(id) { document.write(' '); this.container = document.getElementById(id); }, bind : function(obj, evt, fun)

  • Android点击WebView实现图片缩放及滑动浏览效果

    最近做的项目有一个要求,就是在WebView中显示的html,需要在点击其中的图片时进行放大,并进行缩放和滑动 浏览,我第一想到的是这是和js进行交互的事情,但是怎么获取html中图片的url,并保存起来进行显示,我就不知道 了,所以去查了下资料,最后找到了解决的办法: 博客地址:Android WebView中图片浏览及缩放效果 首先说一下处理这个要求的思路,首先我们要获取到html中的所有图片的url,并保存到集合中,当点击图片时,跳转 一个Activity用ViewPager进行显示,这样

  • Android WebView中图片浏览及缩放效果

    本文实例为大家分享了Android WebView图片浏览及缩放效果展示的具体代码,供大家参考,具体内容如下 此工程用到了两个开源库: PhotoView支持图片的缩放 Android-Universal-Image-Loader图片的异步加载 (android studio)将两个源工程中的library文件夹导入到Demo Module所在的Project中,修改各自的build.gradle文件,让里面的版本号.所用的android包等与Demo Module相同即可.大致如图: 源代码:

  • jquery的幻灯片图片切换效果代码分享

    本文实例讲述了jquery的幻灯片图片切换效果.分享给大家供大家参考.具体如下: 这是一款基于jquery的幻灯片图片切换效果代码,有缩略图和标题,可以自定义标题. 运行效果图:     -------------------查看效果 下载源码------------------- 小提示:浏览器中如果不能正常运行,可以尝试切换浏览模式. (1)在head区域引入CSS样式: <LINK rel=stylesheet type=text/css href="css/lrtk.css&quo

随机推荐